
<!DOCTYPE html>
<html
  lang="zh-cn"
  data-figures=""
  
    class="page"
  
  
  >
  <head>
<title>Linux内核copy_process分析（一） | 拾月国度</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<script>
  var _hmt = _hmt || [];
  (function() {
    var hm = document.createElement("script");
    hm.src = "https://hm.baidu.com/hm.js?c24bad48a3da8c3c532f0c580bb4f8c5";
    var s = document.getElementsByTagName("script")[0];
    s.parentNode.insertBefore(hm, s);
  })();
</script>





<meta property="og:locale" content="zh-cn" />

<meta property="og:type" content="article">
<meta name="description" content="1. copy_process原型 1/// kernel/fork.c 2/* 3 * This creates a new process as a copy of the old one, 4 * but does not actually start it yet. 5 * 6 * It copies the …" />
<meta name="twitter:card" content="summary" />
<meta name="twitter:creator" content="">
<meta name="twitter:title" content="Linux内核copy_process分析（一）" />
<meta name="twitter:image" content="https://kingdix10.gitee.io/covers/cover8.jpg"/>
<meta property="og:url" content="https://kingdix10.gitee.io/post/kernel/linux-6.6/sched/copy_process_1/" />
<meta property="og:title" content="Linux内核copy_process分析（一）" />
<meta property="og:description" content="1. copy_process原型 1/// kernel/fork.c 2/* 3 * This creates a new process as a copy of the old one, 4 * but does not actually start it yet. 5 * 6 * It copies the …" />
<meta property="og:image" content="https://kingdix10.gitee.io/covers/cover8.jpg" />

<link rel="apple-touch-icon" sizes="180x180" href="https://kingdix10.gitee.io/icons/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="https://kingdix10.gitee.io/icons/icon_yellow_transparent.png">
<link rel="manifest" href="https://kingdix10.gitee.io/icons/site.webmanifest">

<link rel="canonical" href="https://kingdix10.gitee.io/post/kernel/linux-6.6/sched/copy_process_1/">



<link rel="preload" href="https://kingdix10.gitee.io/css/styles.42e2c5f6d8cf9c52872666f8d8b2678ad0c426978b9d78aff3c33b7a1e7f6f97f54bcdaf0518a25fb0fe26367d04f8b07c683b3b38b331cb098daadee06b1f3e.css" integrity = "sha512-QuLF9tjPnFKHJmb42LJnitDEJpeLnXiv88M7eh5/b5f1S82vBRiiX7D&#43;JjZ9BPiwfGg7OzizMcsJjare4GsfPg==" as="style" crossorigin="anonymous">



<link rel="preload" href="https://kingdix10.gitee.io/zh-cn/js/bundle.352f6b8ac853443fc909370d968a769ffa303b36042cc66849f2d48d9e5dd951ee86c06130908f5d77ea0e55ec8fed0e5dc26f0f14bbd4ad6dcf35999232e5bc.js" as="script" integrity=
"sha512-NS9rishTRD/JCTcNlop2n/owOzYELMZoSfLUjZ5d2VHuhsBhMJCPXXfqDlXsj&#43;0OXcJvDxS71K1tzzWZkjLlvA==" crossorigin="anonymous">


<link rel="stylesheet" type="text/css" href="https://kingdix10.gitee.io/css/styles.42e2c5f6d8cf9c52872666f8d8b2678ad0c426978b9d78aff3c33b7a1e7f6f97f54bcdaf0518a25fb0fe26367d04f8b07c683b3b38b331cb098daadee06b1f3e.css" integrity="sha512-QuLF9tjPnFKHJmb42LJnitDEJpeLnXiv88M7eh5/b5f1S82vBRiiX7D&#43;JjZ9BPiwfGg7OzizMcsJjare4GsfPg==" crossorigin="anonymous">

  </head>
  <body
    data-code="9"
    data-lines="true"
    id="documentTop"
    data-lang="zh-cn"
  >

<header class="nav_header" >
  <nav class="nav"><a href='https://kingdix10.gitee.io/' class="nav_brand nav_item" title="拾月国度">
  <img src="https://kingdix10.gitee.io/logos/icon_yellow_transparent_72x72.png" class="logo" alt="拾月国度">
  <div class="nav_close">
    <div><svg class="icon">
  <title>open-menu</title>
  <use xlink:href="#open-menu"></use>
</svg>
<svg class="icon">
  <title>closeme</title>
  <use xlink:href="#closeme"></use>
</svg>
</div>
  </div>
</a>

    <div class='nav_body nav_body_left'>
      
      
      
        

  <div class="nav_parent">
    <a href="https://kingdix10.gitee.io/home" class="nav_item" title="主页">主页 </a>
  </div>
  <div class="nav_parent">
    <a href="https://kingdix10.gitee.io/" class="nav_item" title="归档">归档 </a>
  </div>
  <div class="nav_parent">
    <a href="https://kingdix10.gitee.io/" class="nav_item" title="链接">链接 <img src='https://kingdix10.gitee.io/icons/caret-icon.svg' alt="icon" class="nav_icon"></a>
    <div class="nav_sub">
      <span class="nav_child"></span>
        <a href="https://gitee.com/kingdix10" class="nav_child nav_item" title="Gitee">Gitee</a>
        <a href="https://github.com/kingdix10" class="nav_child nav_item" title="GitHub">GitHub</a>
        <a href="https://www.zhihu.com/people/kingdix10" class="nav_child nav_item" title="知乎">知乎</a>
        <a href="https://www.cnblogs.com/kingdix10" class="nav_child nav_item" title="博客园">博客园</a>
        <a href="https://blog.csdn.net/u014001096" class="nav_child nav_item" title="CSDN">CSDN</a>
    </div>
  </div>
  <div class="nav_parent">
    <a href="https://kingdix10.gitee.io/about/" class="nav_item" title="关于">关于 </a>
  </div>
      
      <div class="nav_parent">
        <a href="#" class="nav_item">🌐</a>
        <div class="nav_sub">
          <span class="nav_child"></span>
          
          <a href="https://kingdix10.gitee.io/" class="nav_child nav_item">中文</a>
          
          <a href="https://kingdix10.gitee.io/en/" class="nav_child nav_item">English</a>
          
        </div>
      </div>
<div class='follow'>
  <a href="https://gitee.com/kingdix10">
    <svg class="icon">
  <title>gitee</title>
  <use xlink:href="#gitee"></use>
</svg>

  </a>
  <a href="https://github.com/kingdix10">
    <svg class="icon">
  <title>github</title>
  <use xlink:href="#github"></use>
</svg>

  </a>
    
  <a href="https://kingdix10.gitee.io/index.xml">
    <svg class="icon">
  <title>rss</title>
  <use xlink:href="#rss"></use>
</svg>

  </a>
<div class="color_mode">
  <input type="checkbox" class="color_choice" id="mode">
</div>

</div>

    </div>
  </nav>
</header>

    <main>
<div class="grid-inverse wrap content">
  <article class="post_content">
    <h1 class="post_title">Linux内核copy_process分析（一）</h1>
  <div class="post_meta">
    <span><svg class="icon">
  <title>calendar</title>
  <use xlink:href="#calendar"></use>
</svg>
</span>
    <span class="post_date">
      2022/02/13</span>
    <span class="post_time"> | 10 分钟阅读</span><span>&nbsp;|<a href='https://kingdix10.gitee.io/tags/linux/' title="Linux" class="post_tag button button_translucent">Linux
        </a><a href='https://kingdix10.gitee.io/tags/linux-6.6/' title="linux-6.6" class="post_tag button button_translucent">linux-6.6
        </a>
    </span>
    <span class="page_only">&nbsp;|
  <div class="post_share">
    分享到:

    <a href="https://kingdix10.gitee.io/post/kernel/linux-6.6/sched/copy_process_1/" title="Copy Link" class="link link_yank">
      <svg class="icon">
  <title>copy</title>
  <use xlink:href="#copy"></use>
</svg>

    </a>
  </div>
  
</span>
  </div>



      <div class="post_toc">
        <h2>文章目录</h2>
        <nav id="TableOfContents">
  <ul>
    <li><a href="#1-copy_process原型">1. copy_process原型</a></li>
    <li><a href="#2-局部变量声明">2. 局部变量声明</a></li>
    <li><a href="#3-参数检查">3. 参数检查</a></li>
    <li><a href="#4-当前进程signal处理">4. 当前进程signal处理</a></li>
    <li><a href="#5-dup_task_struct">5. dup_task_struct</a>
      <ul>
        <li><a href="#51-dup_task_struct源码">5.1. dup_task_struct源码</a></li>
      </ul>
    </li>
    <li><a href="#6-flags进程名等设置">6. flags、进程名等设置</a></li>
    <li><a href="#7-copy_creds">7. copy_creds</a>
      <ul>
        <li><a href="#71-copy_creds源码">7.1. copy_creds源码</a></li>
      </ul>
    </li>
    <li><a href="#8-检查是否超过限制和一些其他变量初始化">8. 检查是否超过限制和一些其他变量初始化</a></li>
    <li><a href="#9-统计相关">9. 统计相关</a></li>
    <li><a href="#10-一些变量初始化">10. 一些变量初始化</a></li>
    <li><a href="#11-sched_fork">11. sched_fork</a></li>
    <li><a href="#12-perf_event_init_task">12. perf_event_init_task</a></li>
    <li><a href="#13-audit_alloc">13. audit_alloc</a></li>
  </ul>
</nav>
      </div>
    
    <div class="post_body"><h1 id="1-copy_process原型">1. copy_process原型</h1>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1">/// kernel/fork.c
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="c1"></span><span class="cm">/*
</span></span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="cm"> * This creates a new process as a copy of the old one,
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="cm"> * but does not actually start it yet.
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="cm"> *
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="cm"> * It copies the registers, and all the appropriate
</span></span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="cm"> * parts of the process environment (as per the clone
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="cm"> * flags). The actual kick-off is left to the caller.
</span></span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="cm"> */</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="n">__latent_entropy</span> <span class="k">struct</span> <span class="n">task_struct</span> <span class="o">*</span><span class="nf">copy_process</span><span class="p">(</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">                    <span class="k">struct</span> <span class="n">pid</span> <span class="o">*</span><span class="n">pid</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">                    <span class="kt">int</span> <span class="n">trace</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">                    <span class="kt">int</span> <span class="n">node</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl">                    <span class="k">struct</span> <span class="n">kernel_clone_args</span> <span class="o">*</span><span class="n">args</span><span class="p">)</span>
</span></span></code></pre></div><h1 id="2-局部变量声明">2. 局部变量声明</h1>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="ln">1</span><span class="cl">    <span class="kt">int</span> <span class="n">pidfd</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">retval</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">    <span class="k">struct</span> <span class="n">task_struct</span> <span class="o">*</span><span class="n">p</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">    <span class="k">struct</span> <span class="n">multiprocess_signals</span> <span class="n">delayed</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl">    <span class="k">struct</span> <span class="n">file</span> <span class="o">*</span><span class="n">pidfile</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">    <span class="k">const</span> <span class="n">u64</span> <span class="n">clone_flags</span> <span class="o">=</span> <span class="n">args</span><span class="o">-&gt;</span><span class="n">flags</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl">    <span class="k">struct</span> <span class="n">nsproxy</span> <span class="o">*</span><span class="n">nsp</span> <span class="o">=</span> <span class="n">current</span><span class="o">-&gt;</span><span class="n">nsproxy</span><span class="p">;</span>
</span></span></code></pre></div><h1 id="3-参数检查">3. 参数检查</h1>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="ln"> 1</span><span class="cl">    <span class="cm">/*
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="cm">     * Don&#39;t allow sharing the root directory with processes in a different
</span></span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="cm">     * namespace
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="cm">     */</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">    <span class="k">if</span> <span class="p">((</span><span class="n">clone_flags</span> <span class="o">&amp;</span> <span class="p">(</span><span class="n">CLONE_NEWNS</span><span class="o">|</span><span class="n">CLONE_FS</span><span class="p">))</span> <span class="o">==</span> <span class="p">(</span><span class="n">CLONE_NEWNS</span><span class="o">|</span><span class="n">CLONE_FS</span><span class="p">))</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">        <span class="k">return</span> <span class="nf">ERR_PTR</span><span class="p">(</span><span class="o">-</span><span class="n">EINVAL</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">    <span class="k">if</span> <span class="p">((</span><span class="n">clone_flags</span> <span class="o">&amp;</span> <span class="p">(</span><span class="n">CLONE_NEWUSER</span><span class="o">|</span><span class="n">CLONE_FS</span><span class="p">))</span> <span class="o">==</span> <span class="p">(</span><span class="n">CLONE_NEWUSER</span><span class="o">|</span><span class="n">CLONE_FS</span><span class="p">))</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">        <span class="k">return</span> <span class="nf">ERR_PTR</span><span class="p">(</span><span class="o">-</span><span class="n">EINVAL</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl">    <span class="cm">/*
</span></span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="cm">     * Thread groups must share signals as well, and detached threads
</span></span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="cm">     * can only be started up within the thread group.
</span></span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="cm">     */</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl">    <span class="k">if</span> <span class="p">((</span><span class="n">clone_flags</span> <span class="o">&amp;</span> <span class="n">CLONE_THREAD</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="p">(</span><span class="n">clone_flags</span> <span class="o">&amp;</span> <span class="n">CLONE_SIGHAND</span><span class="p">))</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl">        <span class="k">return</span> <span class="nf">ERR_PTR</span><span class="p">(</span><span class="o">-</span><span class="n">EINVAL</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl">
</span></span><span class="line"><span class="ln">18</span><span class="cl">    <span class="cm">/*
</span></span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="cm">     * Shared signal handlers imply shared VM. By way of the above,
</span></span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="cm">     * thread groups also imply shared VM. Blocking this case allows
</span></span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="cm">     * for various simplifications in other code.
</span></span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="cm">     */</span>
</span></span><span class="line"><span class="ln">23</span><span class="cl">    <span class="k">if</span> <span class="p">((</span><span class="n">clone_flags</span> <span class="o">&amp;</span> <span class="n">CLONE_SIGHAND</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="p">(</span><span class="n">clone_flags</span> <span class="o">&amp;</span> <span class="n">CLONE_VM</span><span class="p">))</span>
</span></span><span class="line"><span class="ln">24</span><span class="cl">        <span class="k">return</span> <span class="nf">ERR_PTR</span><span class="p">(</span><span class="o">-</span><span class="n">EINVAL</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">25</span><span class="cl">
</span></span><span class="line"><span class="ln">26</span><span class="cl">    <span class="cm">/*
</span></span></span><span class="line"><span class="ln">27</span><span class="cl"><span class="cm">     * Siblings of global init remain as zombies on exit since they are
</span></span></span><span class="line"><span class="ln">28</span><span class="cl"><span class="cm">     * not reaped by their parent (swapper). To solve this and to avoid
</span></span></span><span class="line"><span class="ln">29</span><span class="cl"><span class="cm">     * multi-rooted process trees, prevent global and container-inits
</span></span></span><span class="line"><span class="ln">30</span><span class="cl"><span class="cm">     * from creating siblings.
</span></span></span><span class="line"><span class="ln">31</span><span class="cl"><span class="cm">     */</span>
</span></span><span class="line"><span class="ln">32</span><span class="cl">    <span class="k">if</span> <span class="p">((</span><span class="n">clone_flags</span> <span class="o">&amp;</span> <span class="n">CLONE_PARENT</span><span class="p">)</span> <span class="o">&amp;&amp;</span>
</span></span><span class="line"><span class="ln">33</span><span class="cl">                <span class="n">current</span><span class="o">-&gt;</span><span class="n">signal</span><span class="o">-&gt;</span><span class="n">flags</span> <span class="o">&amp;</span> <span class="n">SIGNAL_UNKILLABLE</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">34</span><span class="cl">        <span class="k">return</span> <span class="nf">ERR_PTR</span><span class="p">(</span><span class="o">-</span><span class="n">EINVAL</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">35</span><span class="cl">
</span></span><span class="line"><span class="ln">36</span><span class="cl">    <span class="cm">/*
</span></span></span><span class="line"><span class="ln">37</span><span class="cl"><span class="cm">     * If the new process will be in a different pid or user namespace
</span></span></span><span class="line"><span class="ln">38</span><span class="cl"><span class="cm">     * do not allow it to share a thread group with the forking task.
</span></span></span><span class="line"><span class="ln">39</span><span class="cl"><span class="cm">     */</span>
</span></span><span class="line"><span class="ln">40</span><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">clone_flags</span> <span class="o">&amp;</span> <span class="n">CLONE_THREAD</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">41</span><span class="cl">        <span class="k">if</span> <span class="p">((</span><span class="n">clone_flags</span> <span class="o">&amp;</span> <span class="p">(</span><span class="n">CLONE_NEWUSER</span> <span class="o">|</span> <span class="n">CLONE_NEWPID</span><span class="p">))</span> <span class="o">||</span>
</span></span><span class="line"><span class="ln">42</span><span class="cl">            <span class="p">(</span><span class="nf">task_active_pid_ns</span><span class="p">(</span><span class="n">current</span><span class="p">)</span> <span class="o">!=</span> <span class="n">nsp</span><span class="o">-&gt;</span><span class="n">pid_ns_for_children</span><span class="p">))</span>
</span></span><span class="line"><span class="ln">43</span><span class="cl">            <span class="k">return</span> <span class="nf">ERR_PTR</span><span class="p">(</span><span class="o">-</span><span class="n">EINVAL</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">44</span><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="ln">45</span><span class="cl">
</span></span><span class="line"><span class="ln">46</span><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">clone_flags</span> <span class="o">&amp;</span> <span class="n">CLONE_PIDFD</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">47</span><span class="cl">        <span class="cm">/*
</span></span></span><span class="line"><span class="ln">48</span><span class="cl"><span class="cm">         * - CLONE_DETACHED is blocked so that we can potentially
</span></span></span><span class="line"><span class="ln">49</span><span class="cl"><span class="cm">         *   reuse it later for CLONE_PIDFD.
</span></span></span><span class="line"><span class="ln">50</span><span class="cl"><span class="cm">         * - CLONE_THREAD is blocked until someone really needs it.
</span></span></span><span class="line"><span class="ln">51</span><span class="cl"><span class="cm">         */</span>
</span></span><span class="line"><span class="ln">52</span><span class="cl">        <span class="k">if</span> <span class="p">(</span><span class="n">clone_flags</span> <span class="o">&amp;</span> <span class="p">(</span><span class="n">CLONE_DETACHED</span> <span class="o">|</span> <span class="n">CLONE_THREAD</span><span class="p">))</span>
</span></span><span class="line"><span class="ln">53</span><span class="cl">            <span class="k">return</span> <span class="nf">ERR_PTR</span><span class="p">(</span><span class="o">-</span><span class="n">EINVAL</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">54</span><span class="cl">    <span class="p">}</span>
</span></span></code></pre></div><h1 id="4-当前进程signal处理">4. 当前进程signal处理</h1>
<p>将收到的信号强制分发出去。使用delayed收集在fork过程中发送给进程的信号，以便进行延迟处理。在新进程准备好后，将其记录到新进程的p-&gt;signal-&gt;shared_pending.signal，再进行处理。之后清除pending的信号。完成之后，继续检查是否收到信号，如果收到信号，则fork失败，直接退出。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="ln"> 1</span><span class="cl">    <span class="cm">/*
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="cm">     * Force any signals received before this point to be delivered
</span></span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="cm">     * before the fork happens.  Collect up signals sent to multiple
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="cm">     * processes that happen during the fork and delay them so that
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="cm">     * they appear to happen after the fork.
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="cm">     */</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">    <span class="nf">sigemptyset</span><span class="p">(</span><span class="o">&amp;</span><span class="n">delayed</span><span class="p">.</span><span class="n">signal</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">    <span class="nf">INIT_HLIST_NODE</span><span class="p">(</span><span class="o">&amp;</span><span class="n">delayed</span><span class="p">.</span><span class="n">node</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl">    <span class="nf">spin_lock_irq</span><span class="p">(</span><span class="o">&amp;</span><span class="n">current</span><span class="o">-&gt;</span><span class="n">sighand</span><span class="o">-&gt;</span><span class="n">siglock</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">    <span class="c1">/// delayed记录到父进程的multiprocess，用于收集在新进程fork期间收到的信号
</span></span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="c1"></span>    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="n">clone_flags</span> <span class="o">&amp;</span> <span class="n">CLONE_THREAD</span><span class="p">))</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">        <span class="nf">hlist_add_head</span><span class="p">(</span><span class="o">&amp;</span><span class="n">delayed</span><span class="p">.</span><span class="n">node</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">current</span><span class="o">-&gt;</span><span class="n">signal</span><span class="o">-&gt;</span><span class="n">multiprocess</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl">    <span class="nf">recalc_sigpending</span><span class="p">();</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl">    <span class="nf">spin_unlock_irq</span><span class="p">(</span><span class="o">&amp;</span><span class="n">current</span><span class="o">-&gt;</span><span class="n">sighand</span><span class="o">-&gt;</span><span class="n">siglock</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl">    <span class="n">retval</span> <span class="o">=</span> <span class="o">-</span><span class="n">ERESTARTNOINTR</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nf">task_sigpending</span><span class="p">(</span><span class="n">current</span><span class="p">))</span>       <span class="c1">/// 继续检查是否收到信号
</span></span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="c1"></span>        <span class="k">goto</span> <span class="n">fork_out</span><span class="p">;</span>
</span></span></code></pre></div><h1 id="5-dup_task_struct">5. dup_task_struct</h1>
<p>dup_task_struct基于current创建新的task_struct，和一些其他信息，申请内核栈，初始化新进程的一些变量。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="ln">1</span><span class="cl">    <span class="n">retval</span> <span class="o">=</span> <span class="o">-</span><span class="n">ENOMEM</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">    <span class="n">p</span> <span class="o">=</span> <span class="nf">dup_task_struct</span><span class="p">(</span><span class="n">current</span><span class="p">,</span> <span class="n">node</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">p</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl">        <span class="k">goto</span> <span class="n">fork_out</span><span class="p">;</span>
</span></span></code></pre></div><h2 id="51-dup_task_struct源码">5.1. dup_task_struct源码</h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="ln">  1</span><span class="cl"><span class="k">static</span> <span class="k">struct</span> <span class="n">task_struct</span> <span class="o">*</span><span class="nf">dup_task_struct</span><span class="p">(</span><span class="k">struct</span> <span class="n">task_struct</span> <span class="o">*</span><span class="n">orig</span><span class="p">,</span> <span class="kt">int</span> <span class="n">node</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">  2</span><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="ln">  3</span><span class="cl">    <span class="k">struct</span> <span class="n">task_struct</span> <span class="o">*</span><span class="n">tsk</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">  4</span><span class="cl">    <span class="kt">int</span> <span class="n">err</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">  5</span><span class="cl">
</span></span><span class="line"><span class="ln">  6</span><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">node</span> <span class="o">==</span> <span class="n">NUMA_NO_NODE</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">  7</span><span class="cl">        <span class="n">node</span> <span class="o">=</span> <span class="nf">tsk_fork_get_node</span><span class="p">(</span><span class="n">orig</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">  8</span><span class="cl">    <span class="n">tsk</span> <span class="o">=</span> <span class="nf">alloc_task_struct_node</span><span class="p">(</span><span class="n">node</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">  9</span><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">tsk</span><span class="p">)</span>
</span></span><span class="line"><span class="ln"> 10</span><span class="cl">        <span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 11</span><span class="cl">
</span></span><span class="line"><span class="ln"> 12</span><span class="cl">    <span class="n">err</span> <span class="o">=</span> <span class="nf">arch_dup_task_struct</span><span class="p">(</span><span class="n">tsk</span><span class="p">,</span> <span class="n">orig</span><span class="p">);</span>      <span class="c1">/// 复制task_struct，和一些其他信息
</span></span></span><span class="line"><span class="ln"> 13</span><span class="cl"><span class="c1"></span>    <span class="k">if</span> <span class="p">(</span><span class="n">err</span><span class="p">)</span>
</span></span><span class="line"><span class="ln"> 14</span><span class="cl">        <span class="k">goto</span> <span class="n">free_tsk</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 15</span><span class="cl">
</span></span><span class="line"><span class="ln"> 16</span><span class="cl">    <span class="n">err</span> <span class="o">=</span> <span class="nf">alloc_thread_stack_node</span><span class="p">(</span><span class="n">tsk</span><span class="p">,</span> <span class="n">node</span><span class="p">);</span>   <span class="c1">/// 申请内核栈，记录到tsk-&gt;stack
</span></span></span><span class="line"><span class="ln"> 17</span><span class="cl"><span class="c1"></span>    <span class="k">if</span> <span class="p">(</span><span class="n">err</span><span class="p">)</span>
</span></span><span class="line"><span class="ln"> 18</span><span class="cl">        <span class="k">goto</span> <span class="n">free_tsk</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 19</span><span class="cl">
</span></span><span class="line"><span class="ln"> 20</span><span class="cl"><span class="cp">#ifdef CONFIG_THREAD_INFO_IN_TASK
</span></span></span><span class="line"><span class="ln"> 21</span><span class="cl"><span class="cp"></span>    <span class="nf">refcount_set</span><span class="p">(</span><span class="o">&amp;</span><span class="n">tsk</span><span class="o">-&gt;</span><span class="n">stack_refcount</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 22</span><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="ln"> 23</span><span class="cl"><span class="cp"></span>    <span class="nf">account_kernel_stack</span><span class="p">(</span><span class="n">tsk</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 24</span><span class="cl">
</span></span><span class="line"><span class="ln"> 25</span><span class="cl">    <span class="n">err</span> <span class="o">=</span> <span class="nf">scs_prepare</span><span class="p">(</span><span class="n">tsk</span><span class="p">,</span> <span class="n">node</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 26</span><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">err</span><span class="p">)</span>
</span></span><span class="line"><span class="ln"> 27</span><span class="cl">        <span class="k">goto</span> <span class="n">free_stack</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 28</span><span class="cl">
</span></span><span class="line"><span class="ln"> 29</span><span class="cl"><span class="cp">#ifdef CONFIG_SECCOMP
</span></span></span><span class="line"><span class="ln"> 30</span><span class="cl"><span class="cp"></span>    <span class="cm">/*
</span></span></span><span class="line"><span class="ln"> 31</span><span class="cl"><span class="cm">     * We must handle setting up seccomp filters once we&#39;re under
</span></span></span><span class="line"><span class="ln"> 32</span><span class="cl"><span class="cm">     * the sighand lock in case orig has changed between now and
</span></span></span><span class="line"><span class="ln"> 33</span><span class="cl"><span class="cm">     * then. Until then, filter must be NULL to avoid messing up
</span></span></span><span class="line"><span class="ln"> 34</span><span class="cl"><span class="cm">     * the usage counts on the error path calling free_task.
</span></span></span><span class="line"><span class="ln"> 35</span><span class="cl"><span class="cm">     */</span>
</span></span><span class="line"><span class="ln"> 36</span><span class="cl">    <span class="n">tsk</span><span class="o">-&gt;</span><span class="n">seccomp</span><span class="p">.</span><span class="n">filter</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 37</span><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="ln"> 38</span><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="ln"> 39</span><span class="cl">    <span class="c1">/// 在thread_info独立与task_struct时，将tsk记录到栈，以便使用current获取当前进程
</span></span></span><span class="line"><span class="ln"> 40</span><span class="cl"><span class="c1"></span>    <span class="nf">setup_thread_stack</span><span class="p">(</span><span class="n">tsk</span><span class="p">,</span> <span class="n">orig</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 41</span><span class="cl">    <span class="nf">clear_user_return_notifier</span><span class="p">(</span><span class="n">tsk</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 42</span><span class="cl">    <span class="nf">clear_tsk_need_resched</span><span class="p">(</span><span class="n">tsk</span><span class="p">);</span>        <span class="c1">/// 新建的进程不需要调度
</span></span></span><span class="line"><span class="ln"> 43</span><span class="cl"><span class="c1"></span>    <span class="nf">set_task_stack_end_magic</span><span class="p">(</span><span class="n">tsk</span><span class="p">);</span>      <span class="c1">/// 设置栈底魔数
</span></span></span><span class="line"><span class="ln"> 44</span><span class="cl"><span class="c1"></span>    <span class="nf">clear_syscall_work_syscall_user_dispatch</span><span class="p">(</span><span class="n">tsk</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 45</span><span class="cl">
</span></span><span class="line"><span class="ln"> 46</span><span class="cl"><span class="cp">#ifdef CONFIG_STACKPROTECTOR
</span></span></span><span class="line"><span class="ln"> 47</span><span class="cl"><span class="cp"></span>    <span class="c1">/// Canary value for the -fstack-protector GCC feature
</span></span></span><span class="line"><span class="ln"> 48</span><span class="cl"><span class="c1"></span>    <span class="n">tsk</span><span class="o">-&gt;</span><span class="n">stack_canary</span> <span class="o">=</span> <span class="nf">get_random_canary</span><span class="p">();</span>
</span></span><span class="line"><span class="ln"> 49</span><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="ln"> 50</span><span class="cl"><span class="cp"></span>    <span class="k">if</span> <span class="p">(</span><span class="n">orig</span><span class="o">-&gt;</span><span class="n">cpus_ptr</span> <span class="o">==</span> <span class="o">&amp;</span><span class="n">orig</span><span class="o">-&gt;</span><span class="n">cpus_mask</span><span class="p">)</span>
</span></span><span class="line"><span class="ln"> 51</span><span class="cl">        <span class="n">tsk</span><span class="o">-&gt;</span><span class="n">cpus_ptr</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">tsk</span><span class="o">-&gt;</span><span class="n">cpus_mask</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 52</span><span class="cl">    <span class="nf">dup_user_cpus_ptr</span><span class="p">(</span><span class="n">tsk</span><span class="p">,</span> <span class="n">orig</span><span class="p">,</span> <span class="n">node</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 53</span><span class="cl">
</span></span><span class="line"><span class="ln"> 54</span><span class="cl">    <span class="cm">/*
</span></span></span><span class="line"><span class="ln"> 55</span><span class="cl"><span class="cm">     * One for the user space visible state that goes away when reaped.
</span></span></span><span class="line"><span class="ln"> 56</span><span class="cl"><span class="cm">     * One for the scheduler.
</span></span></span><span class="line"><span class="ln"> 57</span><span class="cl"><span class="cm">     */</span>
</span></span><span class="line"><span class="ln"> 58</span><span class="cl">    <span class="nf">refcount_set</span><span class="p">(</span><span class="o">&amp;</span><span class="n">tsk</span><span class="o">-&gt;</span><span class="n">rcu_users</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>   <span class="c1">/// 进程退出和回收task_struct时使用
</span></span></span><span class="line"><span class="ln"> 59</span><span class="cl"><span class="c1"></span>    <span class="cm">/* One for the rcu users */</span>
</span></span><span class="line"><span class="ln"> 60</span><span class="cl">    <span class="nf">refcount_set</span><span class="p">(</span><span class="o">&amp;</span><span class="n">tsk</span><span class="o">-&gt;</span><span class="n">usage</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>       <span class="c1">/// 回收task_struct时使用
</span></span></span><span class="line"><span class="ln"> 61</span><span class="cl"><span class="c1"></span><span class="cp">#ifdef CONFIG_BLK_DEV_IO_TRACE
</span></span></span><span class="line"><span class="ln"> 62</span><span class="cl"><span class="cp"></span>    <span class="n">tsk</span><span class="o">-&gt;</span><span class="n">btrace_seq</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 63</span><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="ln"> 64</span><span class="cl"><span class="cp"></span>    <span class="n">tsk</span><span class="o">-&gt;</span><span class="n">splice_pipe</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 65</span><span class="cl">    <span class="n">tsk</span><span class="o">-&gt;</span><span class="n">task_frag</span><span class="p">.</span><span class="n">page</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 66</span><span class="cl">    <span class="n">tsk</span><span class="o">-&gt;</span><span class="n">wake_q</span><span class="p">.</span><span class="n">next</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 67</span><span class="cl">    <span class="n">tsk</span><span class="o">-&gt;</span><span class="n">worker_private</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 68</span><span class="cl">
</span></span><span class="line"><span class="ln"> 69</span><span class="cl">    <span class="nf">kcov_task_init</span><span class="p">(</span><span class="n">tsk</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 70</span><span class="cl">    <span class="nf">kmsan_task_create</span><span class="p">(</span><span class="n">tsk</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 71</span><span class="cl">    <span class="nf">kmap_local_fork</span><span class="p">(</span><span class="n">tsk</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 72</span><span class="cl">
</span></span><span class="line"><span class="ln"> 73</span><span class="cl"><span class="cp">#ifdef CONFIG_FAULT_INJECTION
</span></span></span><span class="line"><span class="ln"> 74</span><span class="cl"><span class="cp"></span>    <span class="n">tsk</span><span class="o">-&gt;</span><span class="n">fail_nth</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 75</span><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="ln"> 76</span><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="ln"> 77</span><span class="cl"><span class="cp">#ifdef CONFIG_BLK_CGROUP
</span></span></span><span class="line"><span class="ln"> 78</span><span class="cl"><span class="cp"></span>    <span class="n">tsk</span><span class="o">-&gt;</span><span class="n">throttle_disk</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 79</span><span class="cl">    <span class="n">tsk</span><span class="o">-&gt;</span><span class="n">use_memdelay</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 80</span><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="ln"> 81</span><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="ln"> 82</span><span class="cl"><span class="cp">#ifdef CONFIG_IOMMU_SVA
</span></span></span><span class="line"><span class="ln"> 83</span><span class="cl"><span class="cp"></span>    <span class="n">tsk</span><span class="o">-&gt;</span><span class="n">pasid_activated</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 84</span><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="ln"> 85</span><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="ln"> 86</span><span class="cl"><span class="cp">#ifdef CONFIG_MEMCG
</span></span></span><span class="line"><span class="ln"> 87</span><span class="cl"><span class="cp"></span>    <span class="n">tsk</span><span class="o">-&gt;</span><span class="n">active_memcg</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 88</span><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="ln"> 89</span><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="ln"> 90</span><span class="cl"><span class="cp">#ifdef CONFIG_CPU_SUP_INTEL
</span></span></span><span class="line"><span class="ln"> 91</span><span class="cl"><span class="cp"></span>    <span class="n">tsk</span><span class="o">-&gt;</span><span class="n">reported_split_lock</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 92</span><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="ln"> 93</span><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="ln"> 94</span><span class="cl"><span class="cp">#ifdef CONFIG_SCHED_MM_CID
</span></span></span><span class="line"><span class="ln"> 95</span><span class="cl"><span class="cp"></span>    <span class="n">tsk</span><span class="o">-&gt;</span><span class="n">mm_cid</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 96</span><span class="cl">    <span class="n">tsk</span><span class="o">-&gt;</span><span class="n">last_mm_cid</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 97</span><span class="cl">    <span class="n">tsk</span><span class="o">-&gt;</span><span class="n">mm_cid_active</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 98</span><span class="cl">    <span class="n">tsk</span><span class="o">-&gt;</span><span class="n">migrate_from_cpu</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 99</span><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="ln">100</span><span class="cl"><span class="cp"></span>    <span class="k">return</span> <span class="n">tsk</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">101</span><span class="cl">
</span></span><span class="line"><span class="ln">102</span><span class="cl"><span class="nl">free_stack</span><span class="p">:</span>
</span></span><span class="line"><span class="ln">103</span><span class="cl">    <span class="nf">exit_task_stack_account</span><span class="p">(</span><span class="n">tsk</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">104</span><span class="cl">    <span class="nf">free_thread_stack</span><span class="p">(</span><span class="n">tsk</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">105</span><span class="cl"><span class="nl">free_tsk</span><span class="p">:</span>
</span></span><span class="line"><span class="ln">106</span><span class="cl">    <span class="nf">free_task_struct</span><span class="p">(</span><span class="n">tsk</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">107</span><span class="cl">    <span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">108</span><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h1 id="6-flags进程名等设置">6. flags、进程名等设置</h1>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="ln"> 1</span><span class="cl">    <span class="n">p</span><span class="o">-&gt;</span><span class="n">flags</span> <span class="o">&amp;=</span> <span class="o">~</span><span class="n">PF_KTHREAD</span><span class="p">;</span>        <span class="c1">/// 默认不是内核线程
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="c1"></span>    <span class="k">if</span> <span class="p">(</span><span class="n">args</span><span class="o">-&gt;</span><span class="n">kthread</span><span class="p">)</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">        <span class="n">p</span><span class="o">-&gt;</span><span class="n">flags</span> <span class="o">|=</span> <span class="n">PF_KTHREAD</span><span class="p">;</span>     <span class="c1">/// 如果时内核线程，设置PF_KTHREAD
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="c1"></span>    <span class="k">if</span> <span class="p">(</span><span class="n">args</span><span class="o">-&gt;</span><span class="n">user_worker</span><span class="p">)</span> <span class="p">{</span>        <span class="c1">/// 如果是user worker，阻止非致命信号和STOP
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="c1"></span>        <span class="cm">/*
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="cm">         * Mark us a user worker, and block any signal that isn&#39;t
</span></span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="cm">         * fatal or STOP
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="cm">         */</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">        <span class="n">p</span><span class="o">-&gt;</span><span class="n">flags</span> <span class="o">|=</span> <span class="n">PF_USER_WORKER</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">        <span class="nf">siginitsetinv</span><span class="p">(</span><span class="o">&amp;</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">blocked</span><span class="p">,</span> <span class="nf">sigmask</span><span class="p">(</span><span class="n">SIGKILL</span><span class="p">)</span><span class="o">|</span><span class="nf">sigmask</span><span class="p">(</span><span class="n">SIGSTOP</span><span class="p">));</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">args</span><span class="o">-&gt;</span><span class="n">io_thread</span><span class="p">)</span>            <span class="c1">/// io线程
</span></span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="c1"></span>        <span class="n">p</span><span class="o">-&gt;</span><span class="n">flags</span> <span class="o">|=</span> <span class="n">PF_IO_WORKER</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl">
</span></span><span class="line"><span class="ln">15</span><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">args</span><span class="o">-&gt;</span><span class="n">name</span><span class="p">)</span>                 <span class="c1">/// 设置进程名
</span></span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="c1"></span>        <span class="nf">strscpy_pad</span><span class="p">(</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">comm</span><span class="p">,</span> <span class="n">args</span><span class="o">-&gt;</span><span class="n">name</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">comm</span><span class="p">));</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl">
</span></span><span class="line"><span class="ln">18</span><span class="cl">    <span class="c1">/// 父设置子进程的pid
</span></span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="c1"></span>    <span class="n">p</span><span class="o">-&gt;</span><span class="n">set_child_tid</span> <span class="o">=</span> <span class="p">(</span><span class="n">clone_flags</span> <span class="o">&amp;</span> <span class="n">CLONE_CHILD_SETTID</span><span class="p">)</span> <span class="o">?</span> <span class="n">args</span><span class="o">-&gt;</span><span class="nl">child_tid</span> <span class="p">:</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">20</span><span class="cl">    <span class="cm">/*
</span></span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="cm">     * Clear TID on mm_release()?
</span></span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="cm">     */</span>
</span></span><span class="line"><span class="ln">23</span><span class="cl">    <span class="n">p</span><span class="o">-&gt;</span><span class="n">clear_child_tid</span> <span class="o">=</span> <span class="p">(</span><span class="n">clone_flags</span> <span class="o">&amp;</span> <span class="n">CLONE_CHILD_CLEARTID</span><span class="p">)</span> <span class="o">?</span> <span class="n">args</span><span class="o">-&gt;</span><span class="nl">child_tid</span> <span class="p">:</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">24</span><span class="cl">
</span></span><span class="line"><span class="ln">25</span><span class="cl">    <span class="nf">ftrace_graph_init_task</span><span class="p">(</span><span class="n">p</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">26</span><span class="cl">
</span></span><span class="line"><span class="ln">27</span><span class="cl">    <span class="nf">rt_mutex_init_task</span><span class="p">(</span><span class="n">p</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">28</span><span class="cl">
</span></span><span class="line"><span class="ln">29</span><span class="cl">    <span class="nf">lockdep_assert_irqs_enabled</span><span class="p">();</span>
</span></span><span class="line"><span class="ln">30</span><span class="cl"><span class="cp">#ifdef CONFIG_PROVE_LOCKING
</span></span></span><span class="line"><span class="ln">31</span><span class="cl"><span class="cp"></span>    <span class="nf">DEBUG_LOCKS_WARN_ON</span><span class="p">(</span><span class="o">!</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">softirqs_enabled</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">32</span><span class="cl"><span class="cp">#endif
</span></span></span></code></pre></div><h1 id="7-copy_creds">7. copy_creds</h1>
<p>如果clone_flags包含CLONE_THREAD，与父进程共享凭证，否则创建新的凭证。包含进程的UID和GID等信息。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="ln">1</span><span class="cl">    <span class="n">retval</span> <span class="o">=</span> <span class="nf">copy_creds</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">clone_flags</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">retval</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">        <span class="k">goto</span> <span class="n">bad_fork_free</span><span class="p">;</span>
</span></span></code></pre></div><h2 id="71-copy_creds源码">7.1. copy_creds源码</h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1">/// kernel/cred.c
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="c1"></span><span class="cm">/*
</span></span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="cm"> * Copy credentials for the new process created by fork()
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="cm"> *
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="cm"> * We share if we can, but under some circumstances we have to generate a new
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="cm"> * set.
</span></span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="cm"> *
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="cm"> * The new process gets the current process&#39;s subjective credentials as its
</span></span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="cm"> * objective and subjective credentials
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="cm"> */</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="kt">int</span> <span class="nf">copy_creds</span><span class="p">(</span><span class="k">struct</span> <span class="n">task_struct</span> <span class="o">*</span><span class="n">p</span><span class="p">,</span> <span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">clone_flags</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">    <span class="k">struct</span> <span class="n">cred</span> <span class="o">*</span><span class="n">new</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl">    <span class="kt">int</span> <span class="n">ret</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl">
</span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="cp">#ifdef CONFIG_KEYS_REQUEST_CACHE
</span></span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="cp"></span>    <span class="n">p</span><span class="o">-&gt;</span><span class="n">cached_requested_key</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="ln">20</span><span class="cl">    <span class="k">if</span> <span class="p">(</span>
</span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="cp">#ifdef CONFIG_KEYS
</span></span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="cp"></span>        <span class="o">!</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">cred</span><span class="o">-&gt;</span><span class="n">thread_keyring</span> <span class="o">&amp;&amp;</span>
</span></span><span class="line"><span class="ln">23</span><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="ln">24</span><span class="cl"><span class="cp"></span>        <span class="n">clone_flags</span> <span class="o">&amp;</span> <span class="n">CLONE_THREAD</span>
</span></span><span class="line"><span class="ln">25</span><span class="cl">        <span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">26</span><span class="cl">        <span class="n">p</span><span class="o">-&gt;</span><span class="n">real_cred</span> <span class="o">=</span> <span class="nf">get_cred</span><span class="p">(</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">cred</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">27</span><span class="cl">        <span class="nf">get_cred</span><span class="p">(</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">cred</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">28</span><span class="cl">        <span class="nf">alter_cred_subscribers</span><span class="p">(</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">cred</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">29</span><span class="cl">        <span class="nf">kdebug</span><span class="p">(</span><span class="s">&#34;share_creds(%p{%d,%d})&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">30</span><span class="cl">               <span class="n">p</span><span class="o">-&gt;</span><span class="n">cred</span><span class="p">,</span> <span class="nf">atomic_read</span><span class="p">(</span><span class="o">&amp;</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">cred</span><span class="o">-&gt;</span><span class="n">usage</span><span class="p">),</span>
</span></span><span class="line"><span class="ln">31</span><span class="cl">               <span class="nf">read_cred_subscribers</span><span class="p">(</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">cred</span><span class="p">));</span>
</span></span><span class="line"><span class="ln">32</span><span class="cl">        <span class="nf">inc_rlimit_ucounts</span><span class="p">(</span><span class="nf">task_ucounts</span><span class="p">(</span><span class="n">p</span><span class="p">),</span> <span class="n">UCOUNT_RLIMIT_NPROC</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">33</span><span class="cl">        <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">34</span><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="ln">35</span><span class="cl">
</span></span><span class="line"><span class="ln">36</span><span class="cl">    <span class="n">new</span> <span class="o">=</span> <span class="nf">prepare_creds</span><span class="p">();</span>
</span></span><span class="line"><span class="ln">37</span><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">new</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">38</span><span class="cl">        <span class="k">return</span> <span class="o">-</span><span class="n">ENOMEM</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">39</span><span class="cl">
</span></span><span class="line"><span class="ln">40</span><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">clone_flags</span> <span class="o">&amp;</span> <span class="n">CLONE_NEWUSER</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">41</span><span class="cl">        <span class="n">ret</span> <span class="o">=</span> <span class="nf">create_user_ns</span><span class="p">(</span><span class="n">new</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">42</span><span class="cl">        <span class="k">if</span> <span class="p">(</span><span class="n">ret</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">43</span><span class="cl">            <span class="k">goto</span> <span class="n">error_put</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">44</span><span class="cl">        <span class="n">ret</span> <span class="o">=</span> <span class="nf">set_cred_ucounts</span><span class="p">(</span><span class="n">new</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">45</span><span class="cl">        <span class="k">if</span> <span class="p">(</span><span class="n">ret</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">46</span><span class="cl">            <span class="k">goto</span> <span class="n">error_put</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">47</span><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="ln">48</span><span class="cl">
</span></span><span class="line"><span class="ln">49</span><span class="cl"><span class="cp">#ifdef CONFIG_KEYS
</span></span></span><span class="line"><span class="ln">50</span><span class="cl"><span class="cp"></span>    <span class="cm">/* new threads get their own thread keyrings if their parent already
</span></span></span><span class="line"><span class="ln">51</span><span class="cl"><span class="cm">     * had one */</span>
</span></span><span class="line"><span class="ln">52</span><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">new</span><span class="o">-&gt;</span><span class="n">thread_keyring</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">53</span><span class="cl">        <span class="nf">key_put</span><span class="p">(</span><span class="n">new</span><span class="o">-&gt;</span><span class="n">thread_keyring</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">54</span><span class="cl">        <span class="n">new</span><span class="o">-&gt;</span><span class="n">thread_keyring</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">55</span><span class="cl">        <span class="k">if</span> <span class="p">(</span><span class="n">clone_flags</span> <span class="o">&amp;</span> <span class="n">CLONE_THREAD</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">56</span><span class="cl">            <span class="nf">install_thread_keyring_to_cred</span><span class="p">(</span><span class="n">new</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">57</span><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="ln">58</span><span class="cl">
</span></span><span class="line"><span class="ln">59</span><span class="cl">    <span class="cm">/* The process keyring is only shared between the threads in a process;
</span></span></span><span class="line"><span class="ln">60</span><span class="cl"><span class="cm">     * anything outside of those threads doesn&#39;t inherit.
</span></span></span><span class="line"><span class="ln">61</span><span class="cl"><span class="cm">     */</span>
</span></span><span class="line"><span class="ln">62</span><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="n">clone_flags</span> <span class="o">&amp;</span> <span class="n">CLONE_THREAD</span><span class="p">))</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">63</span><span class="cl">        <span class="nf">key_put</span><span class="p">(</span><span class="n">new</span><span class="o">-&gt;</span><span class="n">process_keyring</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">64</span><span class="cl">        <span class="n">new</span><span class="o">-&gt;</span><span class="n">process_keyring</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">65</span><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="ln">66</span><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="ln">67</span><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="ln">68</span><span class="cl">    <span class="n">p</span><span class="o">-&gt;</span><span class="n">cred</span> <span class="o">=</span> <span class="n">p</span><span class="o">-&gt;</span><span class="n">real_cred</span> <span class="o">=</span> <span class="nf">get_cred</span><span class="p">(</span><span class="n">new</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">69</span><span class="cl">    <span class="nf">inc_rlimit_ucounts</span><span class="p">(</span><span class="nf">task_ucounts</span><span class="p">(</span><span class="n">p</span><span class="p">),</span> <span class="n">UCOUNT_RLIMIT_NPROC</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">70</span><span class="cl">    <span class="nf">alter_cred_subscribers</span><span class="p">(</span><span class="n">new</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">71</span><span class="cl">    <span class="nf">validate_creds</span><span class="p">(</span><span class="n">new</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">72</span><span class="cl">    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">73</span><span class="cl">
</span></span><span class="line"><span class="ln">74</span><span class="cl"><span class="nl">error_put</span><span class="p">:</span>
</span></span><span class="line"><span class="ln">75</span><span class="cl">    <span class="nf">put_cred</span><span class="p">(</span><span class="n">new</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">76</span><span class="cl">    <span class="k">return</span> <span class="n">ret</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">77</span><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h1 id="8-检查是否超过限制和一些其他变量初始化">8. 检查是否超过限制和一些其他变量初始化</h1>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="ln"> 1</span><span class="cl">    <span class="n">retval</span> <span class="o">=</span> <span class="o">-</span><span class="n">EAGAIN</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">    <span class="c1">/// 检查NPROC是否超过限制
</span></span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="c1"></span>    <span class="k">if</span> <span class="p">(</span><span class="nf">is_rlimit_overlimit</span><span class="p">(</span><span class="nf">task_ucounts</span><span class="p">(</span><span class="n">p</span><span class="p">),</span> <span class="n">UCOUNT_RLIMIT_NPROC</span><span class="p">,</span> <span class="nf">rlimit</span><span class="p">(</span><span class="n">RLIMIT_NPROC</span><span class="p">)))</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">        <span class="c1">/// 检查是否有管理权限
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="c1"></span>        <span class="k">if</span> <span class="p">(</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">real_cred</span><span class="o">-&gt;</span><span class="n">user</span> <span class="o">!=</span> <span class="n">INIT_USER</span> <span class="o">&amp;&amp;</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">            <span class="o">!</span><span class="nf">capable</span><span class="p">(</span><span class="n">CAP_SYS_RESOURCE</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="nf">capable</span><span class="p">(</span><span class="n">CAP_SYS_ADMIN</span><span class="p">))</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">            <span class="k">goto</span> <span class="n">bad_fork_cleanup_count</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">    <span class="n">current</span><span class="o">-&gt;</span><span class="n">flags</span> <span class="o">&amp;=</span> <span class="o">~</span><span class="n">PF_NPROC_EXCEEDED</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl">    <span class="cm">/*
</span></span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="cm">     * If multiple threads are within copy_process(), then this check
</span></span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="cm">     * triggers too late. This doesn&#39;t hurt, the check is only there
</span></span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="cm">     * to stop root fork bombs.
</span></span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="cm">     */</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl">    <span class="n">retval</span> <span class="o">=</span> <span class="o">-</span><span class="n">EAGAIN</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl">    <span class="c1">/// 线程数是否超过限制，超过限制会返回-EAGAIN
</span></span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="c1"></span>    <span class="k">if</span> <span class="p">(</span><span class="nf">data_race</span><span class="p">(</span><span class="n">nr_threads</span> <span class="o">&gt;=</span> <span class="n">max_threads</span><span class="p">))</span>
</span></span><span class="line"><span class="ln">19</span><span class="cl">        <span class="k">goto</span> <span class="n">bad_fork_cleanup_count</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">20</span><span class="cl">
</span></span><span class="line"><span class="ln">21</span><span class="cl">    <span class="nf">delayacct_tsk_init</span><span class="p">(</span><span class="n">p</span><span class="p">);</span>	<span class="cm">/* Must remain after dup_task_struct() */</span>
</span></span><span class="line"><span class="ln">22</span><span class="cl">    <span class="n">p</span><span class="o">-&gt;</span><span class="n">flags</span> <span class="o">&amp;=</span> <span class="o">~</span><span class="p">(</span><span class="n">PF_SUPERPRIV</span> <span class="o">|</span> <span class="n">PF_WQ_WORKER</span> <span class="o">|</span> <span class="n">PF_IDLE</span> <span class="o">|</span> <span class="n">PF_NO_SETAFFINITY</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">23</span><span class="cl">    <span class="n">p</span><span class="o">-&gt;</span><span class="n">flags</span> <span class="o">|=</span> <span class="n">PF_FORKNOEXEC</span><span class="p">;</span>          <span class="c1">/// Forked but didn&#39;t exec
</span></span></span><span class="line"><span class="ln">24</span><span class="cl"><span class="c1"></span>    <span class="nf">INIT_LIST_HEAD</span><span class="p">(</span><span class="o">&amp;</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">children</span><span class="p">);</span>       <span class="c1">/// 新创建的进程，子进程和兄弟进程列表都为空
</span></span></span><span class="line"><span class="ln">25</span><span class="cl"><span class="c1"></span>    <span class="nf">INIT_LIST_HEAD</span><span class="p">(</span><span class="o">&amp;</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">sibling</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">26</span><span class="cl">    <span class="nf">rcu_copy_process</span><span class="p">(</span><span class="n">p</span><span class="p">);</span>                <span class="c1">/// 初始化rcu相关成员
</span></span></span><span class="line"><span class="ln">27</span><span class="cl"><span class="c1"></span>    <span class="n">p</span><span class="o">-&gt;</span><span class="n">vfork_done</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>               <span class="c1">/// 清空父进程的vfork信息
</span></span></span><span class="line"><span class="ln">28</span><span class="cl"><span class="c1"></span>    <span class="nf">spin_lock_init</span><span class="p">(</span><span class="o">&amp;</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">alloc_lock</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">29</span><span class="cl">
</span></span><span class="line"><span class="ln">30</span><span class="cl">    <span class="nf">init_sigpending</span><span class="p">(</span><span class="o">&amp;</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">pending</span><span class="p">);</span>       <span class="c1">/// 清空signal
</span></span></span><span class="line"><span class="ln">31</span><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="ln">32</span><span class="cl">    <span class="n">p</span><span class="o">-&gt;</span><span class="n">utime</span> <span class="o">=</span> <span class="n">p</span><span class="o">-&gt;</span><span class="n">stime</span> <span class="o">=</span> <span class="n">p</span><span class="o">-&gt;</span><span class="n">gtime</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">33</span><span class="cl"><span class="cp">#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
</span></span></span><span class="line"><span class="ln">34</span><span class="cl"><span class="cp"></span>    <span class="n">p</span><span class="o">-&gt;</span><span class="n">utimescaled</span> <span class="o">=</span> <span class="n">p</span><span class="o">-&gt;</span><span class="n">stimescaled</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">35</span><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="ln">36</span><span class="cl"><span class="cp"></span>    <span class="nf">prev_cputime_init</span><span class="p">(</span><span class="o">&amp;</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">prev_cputime</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">37</span><span class="cl">
</span></span><span class="line"><span class="ln">38</span><span class="cl"><span class="cp">#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
</span></span></span><span class="line"><span class="ln">39</span><span class="cl"><span class="cp"></span>    <span class="nf">seqcount_init</span><span class="p">(</span><span class="o">&amp;</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">vtime</span><span class="p">.</span><span class="n">seqcount</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">40</span><span class="cl">    <span class="n">p</span><span class="o">-&gt;</span><span class="n">vtime</span><span class="p">.</span><span class="n">starttime</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">41</span><span class="cl">    <span class="n">p</span><span class="o">-&gt;</span><span class="n">vtime</span><span class="p">.</span><span class="n">state</span> <span class="o">=</span> <span class="n">VTIME_INACTIVE</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">42</span><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="ln">43</span><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="ln">44</span><span class="cl"><span class="cp">#ifdef CONFIG_IO_URING
</span></span></span><span class="line"><span class="ln">45</span><span class="cl"><span class="cp"></span>    <span class="n">p</span><span class="o">-&gt;</span><span class="n">io_uring</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">46</span><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="ln">47</span><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="ln">48</span><span class="cl"><span class="cp">#if defined(SPLIT_RSS_COUNTING)
</span></span></span><span class="line"><span class="ln">49</span><span class="cl"><span class="cp"></span>    <span class="nf">memset</span><span class="p">(</span><span class="o">&amp;</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">rss_stat</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">rss_stat</span><span class="p">));</span>
</span></span><span class="line"><span class="ln">50</span><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="ln">51</span><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="ln">52</span><span class="cl">    <span class="n">p</span><span class="o">-&gt;</span><span class="n">default_timer_slack_ns</span> <span class="o">=</span> <span class="n">current</span><span class="o">-&gt;</span><span class="n">timer_slack_ns</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">53</span><span class="cl">
</span></span><span class="line"><span class="ln">54</span><span class="cl"><span class="cp">#ifdef CONFIG_PSI
</span></span></span><span class="line"><span class="ln">55</span><span class="cl"><span class="cp"></span>    <span class="n">p</span><span class="o">-&gt;</span><span class="n">psi_flags</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">56</span><span class="cl"><span class="cp">#endif
</span></span></span></code></pre></div><h1 id="9-统计相关">9. 统计相关</h1>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="ln">1</span><span class="cl">    <span class="nf">task_io_accounting_init</span><span class="p">(</span><span class="o">&amp;</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">ioac</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">    <span class="c1">/// acct_clear_integrals - clear the mm integral fields in task_struct
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="c1"></span>    <span class="nf">acct_clear_integrals</span><span class="p">(</span><span class="n">p</span><span class="p">);</span>
</span></span></code></pre></div><h1 id="10-一些变量初始化">10. 一些变量初始化</h1>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="ln"> 1</span><span class="cl">    <span class="nf">posix_cputimers_init</span><span class="p">(</span><span class="o">&amp;</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">posix_cputimers</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">    <span class="n">p</span><span class="o">-&gt;</span><span class="n">io_context</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">    <span class="nf">audit_set_context</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">    <span class="nf">cgroup_fork</span><span class="p">(</span><span class="n">p</span><span class="p">);</span>                         <span class="c1">/// 设置cgroups为init_css_set，清空cg_list
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="c1"></span>    <span class="k">if</span> <span class="p">(</span><span class="n">args</span><span class="o">-&gt;</span><span class="n">kthread</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nf">set_kthread_struct</span><span class="p">(</span><span class="n">p</span><span class="p">))</span>         <span class="c1">/// 申请kthread数据并赋值给worker_private，同时设置vfork_done
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="c1"></span>            <span class="k">goto</span> <span class="n">bad_fork_cleanup_delayacct</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="cp">#ifdef CONFIG_NUMA
</span></span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="cp"></span>    <span class="n">p</span><span class="o">-&gt;</span><span class="n">mempolicy</span> <span class="o">=</span> <span class="nf">mpol_dup</span><span class="p">(</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">mempolicy</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nf">IS_ERR</span><span class="p">(</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">mempolicy</span><span class="p">))</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">        <span class="n">retval</span> <span class="o">=</span> <span class="nf">PTR_ERR</span><span class="p">(</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">mempolicy</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl">        <span class="n">p</span><span class="o">-&gt;</span><span class="n">mempolicy</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl">        <span class="k">goto</span> <span class="n">bad_fork_cleanup_delayacct</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="cp">#ifdef CONFIG_CPUSETS
</span></span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="cp"></span>    <span class="n">p</span><span class="o">-&gt;</span><span class="n">cpuset_mem_spread_rotor</span> <span class="o">=</span> <span class="n">NUMA_NO_NODE</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">20</span><span class="cl">    <span class="n">p</span><span class="o">-&gt;</span><span class="n">cpuset_slab_spread_rotor</span> <span class="o">=</span> <span class="n">NUMA_NO_NODE</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">21</span><span class="cl">    <span class="nf">seqcount_spinlock_init</span><span class="p">(</span><span class="o">&amp;</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">mems_allowed_seq</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">alloc_lock</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="ln">23</span><span class="cl"><span class="cp">#ifdef CONFIG_TRACE_IRQFLAGS
</span></span></span><span class="line"><span class="ln">24</span><span class="cl"><span class="cp"></span>    <span class="nf">memset</span><span class="p">(</span><span class="o">&amp;</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">irqtrace</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">irqtrace</span><span class="p">));</span>
</span></span><span class="line"><span class="ln">25</span><span class="cl">    <span class="n">p</span><span class="o">-&gt;</span><span class="n">irqtrace</span><span class="p">.</span><span class="n">hardirq_disable_ip</span>	<span class="o">=</span> <span class="n">_THIS_IP_</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">26</span><span class="cl">    <span class="n">p</span><span class="o">-&gt;</span><span class="n">irqtrace</span><span class="p">.</span><span class="n">softirq_enable_ip</span>	<span class="o">=</span> <span class="n">_THIS_IP_</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">27</span><span class="cl">    <span class="n">p</span><span class="o">-&gt;</span><span class="n">softirqs_enabled</span>		<span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">28</span><span class="cl">    <span class="n">p</span><span class="o">-&gt;</span><span class="n">softirq_context</span>		<span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">29</span><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="ln">30</span><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="ln">31</span><span class="cl">    <span class="n">p</span><span class="o">-&gt;</span><span class="n">pagefault_disabled</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">32</span><span class="cl">
</span></span><span class="line"><span class="ln">33</span><span class="cl"><span class="cp">#ifdef CONFIG_LOCKDEP
</span></span></span><span class="line"><span class="ln">34</span><span class="cl"><span class="cp"></span>    <span class="nf">lockdep_init_task</span><span class="p">(</span><span class="n">p</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">35</span><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="ln">36</span><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="ln">37</span><span class="cl"><span class="cp">#ifdef CONFIG_DEBUG_MUTEXES
</span></span></span><span class="line"><span class="ln">38</span><span class="cl"><span class="cp"></span>    <span class="n">p</span><span class="o">-&gt;</span><span class="n">blocked_on</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span> <span class="cm">/* not blocked yet */</span>
</span></span><span class="line"><span class="ln">39</span><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="ln">40</span><span class="cl"><span class="cp">#ifdef CONFIG_BCACHE
</span></span></span><span class="line"><span class="ln">41</span><span class="cl"><span class="cp"></span>    <span class="n">p</span><span class="o">-&gt;</span><span class="n">sequential_io</span>	<span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">42</span><span class="cl">    <span class="n">p</span><span class="o">-&gt;</span><span class="n">sequential_io_avg</span>	<span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">43</span><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="ln">44</span><span class="cl"><span class="cp">#ifdef CONFIG_BPF_SYSCALL
</span></span></span><span class="line"><span class="ln">45</span><span class="cl"><span class="cp"></span>    <span class="nf">RCU_INIT_POINTER</span><span class="p">(</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">bpf_storage</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">46</span><span class="cl">    <span class="n">p</span><span class="o">-&gt;</span><span class="n">bpf_ctx</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">47</span><span class="cl"><span class="cp">#endif
</span></span></span></code></pre></div><h1 id="11-sched_fork">11. sched_fork</h1>
<p>将新创建的进程状态设置为TASK_NEW，设置调度策略和优先级，初始化负载。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="ln">1</span><span class="cl">    <span class="cm">/* Perform scheduler related setup. Assign this task to a CPU. */</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">    <span class="n">retval</span> <span class="o">=</span> <span class="nf">sched_fork</span><span class="p">(</span><span class="n">clone_flags</span><span class="p">,</span> <span class="n">p</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">retval</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl">        <span class="k">goto</span> <span class="n">bad_fork_cleanup_policy</span><span class="p">;</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1">/// kernel/sched/core.c
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="c1"></span><span class="cm">/*
</span></span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="cm"> * fork()/clone()-time setup:
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="cm"> */</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="kt">int</span> <span class="nf">sched_fork</span><span class="p">(</span><span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">clone_flags</span><span class="p">,</span> <span class="k">struct</span> <span class="n">task_struct</span> <span class="o">*</span><span class="n">p</span><span class="p">)</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">    <span class="nf">__sched_fork</span><span class="p">(</span><span class="n">clone_flags</span><span class="p">,</span> <span class="n">p</span><span class="p">);</span>           <span class="c1">/// 调度相关成员初始化
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="c1"></span>    <span class="cm">/*
</span></span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="cm">     * We mark the process as NEW here. This guarantees that
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="cm">     * nobody will actually run it, and a signal or other external
</span></span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="cm">     * event cannot wake it up and insert it on the runqueue either.
</span></span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="cm">     */</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">    <span class="n">p</span><span class="o">-&gt;</span><span class="n">__state</span> <span class="o">=</span> <span class="n">TASK_NEW</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl">
</span></span><span class="line"><span class="ln">15</span><span class="cl">    <span class="cm">/*
</span></span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="cm">     * Make sure we do not leak PI boosting priority to the child.
</span></span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="cm">     */</span>
</span></span><span class="line"><span class="ln">18</span><span class="cl">    <span class="n">p</span><span class="o">-&gt;</span><span class="n">prio</span> <span class="o">=</span> <span class="n">current</span><span class="o">-&gt;</span><span class="n">normal_prio</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">19</span><span class="cl">
</span></span><span class="line"><span class="ln">20</span><span class="cl">    <span class="nf">uclamp_fork</span><span class="p">(</span><span class="n">p</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">21</span><span class="cl">
</span></span><span class="line"><span class="ln">22</span><span class="cl">    <span class="c1">/// 重置调度策略和优先级
</span></span></span><span class="line"><span class="ln">23</span><span class="cl"><span class="c1"></span>    <span class="cm">/*
</span></span></span><span class="line"><span class="ln">24</span><span class="cl"><span class="cm">     * Revert to default priority/policy on fork if requested.
</span></span></span><span class="line"><span class="ln">25</span><span class="cl"><span class="cm">     */</span>
</span></span><span class="line"><span class="ln">26</span><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nf">unlikely</span><span class="p">(</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">sched_reset_on_fork</span><span class="p">))</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">27</span><span class="cl">        <span class="k">if</span> <span class="p">(</span><span class="nf">task_has_dl_policy</span><span class="p">(</span><span class="n">p</span><span class="p">)</span> <span class="o">||</span> <span class="nf">task_has_rt_policy</span><span class="p">(</span><span class="n">p</span><span class="p">))</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">28</span><span class="cl">            <span class="n">p</span><span class="o">-&gt;</span><span class="n">policy</span> <span class="o">=</span> <span class="n">SCHED_NORMAL</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">29</span><span class="cl">            <span class="n">p</span><span class="o">-&gt;</span><span class="n">static_prio</span> <span class="o">=</span> <span class="nf">NICE_TO_PRIO</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">30</span><span class="cl">            <span class="n">p</span><span class="o">-&gt;</span><span class="n">rt_priority</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">31</span><span class="cl">        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nf">PRIO_TO_NICE</span><span class="p">(</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">static_prio</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">32</span><span class="cl">            <span class="n">p</span><span class="o">-&gt;</span><span class="n">static_prio</span> <span class="o">=</span> <span class="nf">NICE_TO_PRIO</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">33</span><span class="cl">
</span></span><span class="line"><span class="ln">34</span><span class="cl">        <span class="n">p</span><span class="o">-&gt;</span><span class="n">prio</span> <span class="o">=</span> <span class="n">p</span><span class="o">-&gt;</span><span class="n">normal_prio</span> <span class="o">=</span> <span class="n">p</span><span class="o">-&gt;</span><span class="n">static_prio</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">35</span><span class="cl">        <span class="nf">set_load_weight</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="nb">false</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">36</span><span class="cl">
</span></span><span class="line"><span class="ln">37</span><span class="cl">        <span class="cm">/*
</span></span></span><span class="line"><span class="ln">38</span><span class="cl"><span class="cm">         * We don&#39;t need the reset flag anymore after the fork. It has
</span></span></span><span class="line"><span class="ln">39</span><span class="cl"><span class="cm">         * fulfilled its duty:
</span></span></span><span class="line"><span class="ln">40</span><span class="cl"><span class="cm">         */</span>
</span></span><span class="line"><span class="ln">41</span><span class="cl">        <span class="n">p</span><span class="o">-&gt;</span><span class="n">sched_reset_on_fork</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">42</span><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="ln">43</span><span class="cl">
</span></span><span class="line"><span class="ln">44</span><span class="cl">    <span class="c1">/// 根据优先级设置调度策略
</span></span></span><span class="line"><span class="ln">45</span><span class="cl"><span class="c1"></span>    <span class="k">if</span> <span class="p">(</span><span class="nf">dl_prio</span><span class="p">(</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">prio</span><span class="p">))</span>
</span></span><span class="line"><span class="ln">46</span><span class="cl">        <span class="k">return</span> <span class="o">-</span><span class="n">EAGAIN</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">47</span><span class="cl">    <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nf">rt_prio</span><span class="p">(</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">prio</span><span class="p">))</span>
</span></span><span class="line"><span class="ln">48</span><span class="cl">        <span class="n">p</span><span class="o">-&gt;</span><span class="n">sched_class</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">rt_sched_class</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">49</span><span class="cl">    <span class="k">else</span>
</span></span><span class="line"><span class="ln">50</span><span class="cl">        <span class="n">p</span><span class="o">-&gt;</span><span class="n">sched_class</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">fair_sched_class</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">51</span><span class="cl">
</span></span><span class="line"><span class="ln">52</span><span class="cl">    <span class="c1">/// 初始化sched_entity负载
</span></span></span><span class="line"><span class="ln">53</span><span class="cl"><span class="c1"></span>    <span class="nf">init_entity_runnable_average</span><span class="p">(</span><span class="o">&amp;</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">se</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">54</span><span class="cl">
</span></span><span class="line"><span class="ln">55</span><span class="cl">
</span></span><span class="line"><span class="ln">56</span><span class="cl"><span class="cp">#ifdef CONFIG_SCHED_INFO
</span></span></span><span class="line"><span class="ln">57</span><span class="cl"><span class="cp"></span>    <span class="k">if</span> <span class="p">(</span><span class="nf">likely</span><span class="p">(</span><span class="nf">sched_info_on</span><span class="p">()))</span>
</span></span><span class="line"><span class="ln">58</span><span class="cl">        <span class="nf">memset</span><span class="p">(</span><span class="o">&amp;</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">sched_info</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">sched_info</span><span class="p">));</span>
</span></span><span class="line"><span class="ln">59</span><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="ln">60</span><span class="cl"><span class="cp">#if defined(CONFIG_SMP)
</span></span></span><span class="line"><span class="ln">61</span><span class="cl"><span class="cp"></span>    <span class="n">p</span><span class="o">-&gt;</span><span class="n">on_cpu</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">62</span><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="ln">63</span><span class="cl"><span class="cp"></span>    <span class="nf">init_task_preempt_count</span><span class="p">(</span><span class="n">p</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">64</span><span class="cl"><span class="cp">#ifdef CONFIG_SMP
</span></span></span><span class="line"><span class="ln">65</span><span class="cl"><span class="cp"></span>    <span class="nf">plist_node_init</span><span class="p">(</span><span class="o">&amp;</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">pushable_tasks</span><span class="p">,</span> <span class="n">MAX_PRIO</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">66</span><span class="cl">    <span class="nf">RB_CLEAR_NODE</span><span class="p">(</span><span class="o">&amp;</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">pushable_dl_tasks</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">67</span><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="ln">68</span><span class="cl"><span class="cp"></span>    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">69</span><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h1 id="12-perf_event_init_task">12. perf_event_init_task</h1>
<p>初始化perf event上下文</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="ln">1</span><span class="cl">    <span class="n">retval</span> <span class="o">=</span> <span class="nf">perf_event_init_task</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">clone_flags</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">retval</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">        <span class="k">goto</span> <span class="n">bad_fork_cleanup_policy</span><span class="p">;</span>
</span></span></code></pre></div><h1 id="13-audit_alloc">13. audit_alloc</h1>
<p>申请audit上下文。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="ln">1</span><span class="cl">    <span class="n">retval</span> <span class="o">=</span> <span class="nf">audit_alloc</span><span class="p">(</span><span class="n">p</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">retval</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">        <span class="k">goto</span> <span class="n">bad_fork_cleanup_perf</span><span class="p">;</span>
</span></span></code></pre></div>
    </div><div class="post_comments">
  
  
  
</div>



  </article>
<aside class="sidebar">
  <section class="sidebar_inner">
    <br>
    
  
  <div class="search">
    <input type="search" class="search_field form_field" placeholder='搜索内容...' id="find" autocomplete="off" data-scope='post'>
    <label for="find" class="search_label"><svg class="icon">
  <title>search</title>
  <use xlink:href="#search"></use>
</svg>

    </label>
    
    <div class="search_results results"></div>
  </div>

        <div class="author_header">
          <img src="https://kingdix10.gitee.io/logos/icon_yellow_transparent.png" alt="kingdix10 photo">
          <h2>kingdix10</h2>
        </div>
      <div class="author_bio">
        拾月国度
      </div>
      <a href='https://kingdix10.gitee.io/about/' class="button mt-1" role="button" title='阅读更多'>阅读更多</a>

    
      
    
    <h2 class="mt-4">最新文章</h2>
    <ul class="flex-column">
      <li>
        <a href="https://kingdix10.gitee.io/post/kernel/linux-6.6/kdump_crash/arm64_setup/" class="nav-link" title="ARM64 Crash调试环境搭建">ARM64 Crash调试环境搭建</a>
      </li>
      <li>
        <a href="https://kingdix10.gitee.io/post/kernel/linux-6.6/kdump_crash/help/" class="nav-link" title="Crash帮助信息">Crash帮助信息</a>
      </li>
      <li>
        <a href="https://kingdix10.gitee.io/post/kernel/linux-6.1/thermal/thermal/" class="nav-link" title="linux thermal子系统简介">linux thermal子系统简介</a>
      </li>
      <li>
        <a href="https://kingdix10.gitee.io/post/kernel/linux-6.1/time/clocksource_clockevent/" class="nav-link" title="linux内核时间子系统（三）">linux内核时间子系统（三）</a>
      </li>
      <li>
        <a href="https://kingdix10.gitee.io/post/kernel/linux-6.1/time/timekeeping/" class="nav-link" title="linux内核时间子系统（二）">linux内核时间子系统（二）</a>
      </li>
      <li>
        <a href="https://kingdix10.gitee.io/post/kernel/linux-6.1/time/tim/" class="nav-link" title="linux内核时间子系统（一）">linux内核时间子系统（一）</a>
      </li>
      <li>
        <a href="https://kingdix10.gitee.io/post/kernel/linux-6.1/device_driver/device_model/" class="nav-link" title="Linux内核驱动模型（四）核心结构体">Linux内核驱动模型（四）核心结构体</a>
      </li>
      <li>
        <a href="https://kingdix10.gitee.io/post/kernel/linux-6.1/device_driver/initcall/" class="nav-link" title="Linux内核驱动模型（三）驱动初始化">Linux内核驱动模型（三）驱动初始化</a>
      </li>
      <li>
        <a href="https://kingdix10.gitee.io/post/kernel/linux-6.1/fdt/dt_to_dt/" class="nav-link" title="Linux内核驱动模型（二）设备树转换">Linux内核驱动模型（二）设备树转换</a>
      </li>
      <li>
        <a href="https://kingdix10.gitee.io/post/kernel/linux-6.1/fdt/fdt_dt/" class="nav-link" title="Linux内核驱动模型（一）设备树展开">Linux内核驱动模型（一）设备树展开</a>
      </li>
    </ul>
    <div>
      <h2 class="mt-4 taxonomy" id="categories-section">分类</h2>
      <nav class="tags_nav">
        <a href='https://kingdix10.gitee.io/categories/%E8%BF%9B%E7%A8%8B%E7%AE%A1%E7%90%86/' class="post_tag button button_translucent" title="进程管理">
          进程管理
          <span class="button_tally">11</span>
        </a>
        
        <a href='https://kingdix10.gitee.io/categories/%E8%AE%BE%E5%A4%87%E6%A8%A1%E5%9E%8B/' class="post_tag button button_translucent" title="设备模型">
          设备模型
          <span class="button_tally">5</span>
        </a>
        
        <a href='https://kingdix10.gitee.io/categories/4412/' class="post_tag button button_translucent" title="4412">
          4412
          <span class="button_tally">3</span>
        </a>
        
        <a href='https://kingdix10.gitee.io/categories/c%E8%AF%AD%E8%A8%80/' class="post_tag button button_translucent" title="c语言">
          C语言
          <span class="button_tally">3</span>
        </a>
        
        <a href='https://kingdix10.gitee.io/categories/%E5%90%AF%E5%8A%A8%E6%B5%81%E7%A8%8B/' class="post_tag button button_translucent" title="启动流程">
          启动流程
          <span class="button_tally">3</span>
        </a>
        
        <a href='https://kingdix10.gitee.io/categories/%E6%97%B6%E9%97%B4%E5%AD%90%E7%B3%BB%E7%BB%9F/' class="post_tag button button_translucent" title="时间子系统">
          时间子系统
          <span class="button_tally">3</span>
        </a>
        
        <a href='https://kingdix10.gitee.io/categories/kdump-crash/' class="post_tag button button_translucent" title="kdump-crash">
          KDUMP-CRASH
          <span class="button_tally">2</span>
        </a>
        
        <a href='https://kingdix10.gitee.io/categories/%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA/' class="post_tag button button_translucent" title="环境搭建">
          环境搭建
          <span class="button_tally">2</span>
        </a>
        
        <a href='https://kingdix10.gitee.io/categories/linux%E5%91%BD%E4%BB%A4/' class="post_tag button button_translucent" title="linux命令">
          LINUX命令
          <span class="button_tally">1</span>
        </a>
        
        <a href='https://kingdix10.gitee.io/categories/thermal%E5%AD%90%E7%B3%BB%E7%BB%9F/' class="post_tag button button_translucent" title="thermal子系统">
          THERMAL子系统
          <span class="button_tally">1</span>
        </a>
        
        <a href='https://kingdix10.gitee.io/categories/%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86/' class="post_tag button button_translucent" title="内存管理">
          内存管理
          <span class="button_tally">1</span>
        </a>
        
        <a href='https://kingdix10.gitee.io/categories/%E5%86%85%E6%A0%B8%E5%9F%BA%E7%A1%80/' class="post_tag button button_translucent" title="内核基础">
          内核基础
          <span class="button_tally">1</span>
        </a>
        
        <a href='https://kingdix10.gitee.io/categories/%E5%86%85%E6%A0%B8%E8%B0%83%E8%AF%95/' class="post_tag button button_translucent" title="内核调试">
          内核调试
          <span class="button_tally">1</span>
        </a>
        
        
      </nav>
    </div>
    <div>
      <h2 class="mt-4 taxonomy" id="series-section">专栏</h2>
      <nav class="tags_nav">
        <a href='https://kingdix10.gitee.io/series/%E8%BF%9B%E7%A8%8B%E7%AE%A1%E7%90%86/' class="post_tag button button_translucent" title="进程管理">
          进程管理
          <span class="button_tally">11</span>
        </a>
        
        <a href='https://kingdix10.gitee.io/series/%E8%AE%BE%E5%A4%87%E9%A9%B1%E5%8A%A8%E6%A8%A1%E5%9E%8B/' class="post_tag button button_translucent" title="设备驱动模型">
          设备驱动模型
          <span class="button_tally">5</span>
        </a>
        
        <a href='https://kingdix10.gitee.io/series/%E6%97%B6%E9%97%B4%E5%AD%90%E7%B3%BB%E7%BB%9F/' class="post_tag button button_translucent" title="时间子系统">
          时间子系统
          <span class="button_tally">3</span>
        </a>
        
        
      </nav>
    </div>
    <div>
      <h2 class="mt-4 taxonomy" id="tags-section">标签</h2>
      <nav class="tags_nav">
        <a href='https://kingdix10.gitee.io/tags/linux%E5%86%85%E6%A0%B8/' class="post_tag button button_translucent" title="linux内核">
          LINUX内核
          <span class="button_tally">19</span>
        </a>
        
        <a href='https://kingdix10.gitee.io/tags/linux-6.1/' class="post_tag button button_translucent" title="linux-6.1">
          LINUX-6.1
          <span class="button_tally">12</span>
        </a>
        
        <a href='https://kingdix10.gitee.io/tags/linux-6.6/' class="post_tag button button_translucent" title="linux-6.6">
          LINUX-6.6
          <span class="button_tally">9</span>
        </a>
        
        <a href='https://kingdix10.gitee.io/tags/%E5%86%85%E6%A0%B8%E9%A9%B1%E5%8A%A8/' class="post_tag button button_translucent" title="内核驱动">
          内核驱动
          <span class="button_tally">9</span>
        </a>
        
        <a href='https://kingdix10.gitee.io/tags/%E8%BF%9B%E7%A8%8B%E7%AE%A1%E7%90%86/' class="post_tag button button_translucent" title="进程管理">
          进程管理
          <span class="button_tally">6</span>
        </a>
        
        <a href='https://kingdix10.gitee.io/tags/linux/' class="post_tag button button_translucent" title="linux">
          LINUX
          <span class="button_tally">5</span>
        </a>
        
        <a href='https://kingdix10.gitee.io/tags/4412/' class="post_tag button button_translucent" title="4412">
          4412
          <span class="button_tally">3</span>
        </a>
        
        <a href='https://kingdix10.gitee.io/tags/c%E8%AF%AD%E8%A8%80/' class="post_tag button button_translucent" title="c语言">
          C语言
          <span class="button_tally">3</span>
        </a>
        
        <a href='https://kingdix10.gitee.io/tags/%E5%90%AF%E5%8A%A8%E6%B5%81%E7%A8%8B/' class="post_tag button button_translucent" title="启动流程">
          启动流程
          <span class="button_tally">3</span>
        </a>
        
        <a href='https://kingdix10.gitee.io/tags/%E5%B7%A5%E5%85%B7/' class="post_tag button button_translucent" title="工具">
          工具
          <span class="button_tally">3</span>
        </a>
        
        <a href='https://kingdix10.gitee.io/tags/kdump-crash/' class="post_tag button button_translucent" title="kdump-crash">
          KDUMP-CRASH
          <span class="button_tally">2</span>
        </a>
        
        <a href='https://kingdix10.gitee.io/tags/%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA/' class="post_tag button button_translucent" title="环境搭建">
          环境搭建
          <span class="button_tally">2</span>
        </a>
        
        <a href='https://kingdix10.gitee.io/tags/arm64/' class="post_tag button button_translucent" title="arm64">
          ARM64
          <span class="button_tally">1</span>
        </a>
        
        <a href='https://kingdix10.gitee.io/tags/u-boot/' class="post_tag button button_translucent" title="u-boot">
          U-BOOT
          <span class="button_tally">1</span>
        </a>
        
        <a href='https://kingdix10.gitee.io/tags/%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86/' class="post_tag button button_translucent" title="内存管理">
          内存管理
          <span class="button_tally">1</span>
        </a>
        
        <a href='https://kingdix10.gitee.io/tags/%E5%86%85%E6%A0%B8%E8%B0%83%E8%AF%95/' class="post_tag button button_translucent" title="内核调试">
          内核调试
          <span class="button_tally">1</span>
        </a>
        
        <a href='https://kingdix10.gitee.io/tags/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/' class="post_tag button button_translucent" title="数据结构">
          数据结构
          <span class="button_tally">1</span>
        </a>
        
        <a href='https://kingdix10.gitee.io/tags/%E8%B0%83%E8%AF%95/' class="post_tag button button_translucent" title="调试">
          调试
          <span class="button_tally">1</span>
        </a>
        
        
      </nav>
    </div>
  </section>
</aside>

  
</div>
    </main><svg width="0" height="0" class="hidden">
  <symbol viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" id="facebook">
    <path d="M437 0H75C33.648 0 0 33.648 0 75v362c0 41.352 33.648 75 75 75h151V331h-60v-90h60v-61c0-49.629 40.371-90 90-90h91v90h-91v61h91l-15 90h-76v181h121c41.352 0 75-33.648 75-75V75c0-41.352-33.648-75-75-75zm0 0"></path>
  </symbol>
  <symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18.001 18.001" id="twitter">
    <path d="M15.891 4.013c.808-.496 1.343-1.173 1.605-2.034a8.68 8.68 0 0 1-2.351.861c-.703-.756-1.593-1.14-2.66-1.14-1.043 0-1.924.366-2.643 1.078a3.56 3.56 0 0 0-1.076 2.605c0 .309.039.585.117.819-3.076-.105-5.622-1.381-7.628-3.837-.34.601-.51 1.213-.51 1.846 0 1.301.549 2.332 1.645 3.089-.625-.053-1.176-.211-1.645-.47 0 .929.273 1.705.82 2.388a3.623 3.623 0 0 0 2.115 1.291c-.312.08-.641.118-.979.118-.312 0-.533-.026-.664-.083.23.757.664 1.371 1.291 1.841a3.652 3.652 0 0 0 2.152.743C4.148 14.173 2.625 14.69.902 14.69c-.422 0-.721-.006-.902-.038 1.697 1.102 3.586 1.649 5.676 1.649 2.139 0 4.029-.542 5.674-1.626 1.645-1.078 2.859-2.408 3.639-3.974a10.77 10.77 0 0 0 1.172-4.892v-.468a7.788 7.788 0 0 0 1.84-1.921 8.142 8.142 0 0 1-2.11.593z"
      ></path>
  </symbol>
  <symbol aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" id="mail">
    <path  d="M502.3 190.8c3.9-3.1 9.7-.2 9.7 4.7V400c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V195.6c0-5 5.7-7.8 9.7-4.7 22.4 17.4 52.1 39.5 154.1 113.6 21.1 15.4 56.7 47.8 92.2 47.6 35.7.3 72-32.8 92.3-47.6 102-74.1 131.6-96.3 154-113.7zM256 320c23.2.4 56.6-29.2 73.4-41.4 132.7-96.3 142.8-104.7 173.4-128.7 5.8-4.5 9.2-11.5 9.2-18.9v-19c0-26.5-21.5-48-48-48H48C21.5 64 0 85.5 0 112v19c0 7.4 3.4 14.3 9.2 18.9 30.6 23.9 40.7 32.4 173.4 128.7 16.8 12.2 50.2 41.8 73.4 41.4z"></path>
  </symbol>
  <symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" id="calendar">
    <path d="M452 40h-24V0h-40v40H124V0H84v40H60C26.916 40 0 66.916 0 100v352c0 33.084 26.916 60 60 60h392c33.084 0 60-26.916 60-60V100c0-33.084-26.916-60-60-60zm20 412c0 11.028-8.972 20-20 20H60c-11.028 0-20-8.972-20-20V188h432v264zm0-304H40v-48c0-11.028 8.972-20 20-20h24v40h40V80h264v40h40V80h24c11.028 0 20 8.972 20 20v48z"></path>
    <path d="M76 230h40v40H76zm80 0h40v40h-40zm80 0h40v40h-40zm80 0h40v40h-40zm80 0h40v40h-40zM76 310h40v40H76zm80 0h40v40h-40zm80 0h40v40h-40zm80 0h40v40h-40zM76 390h40v40H76zm80 0h40v40h-40zm80 0h40v40h-40zm80 0h40v40h-40zm80-80h40v40h-40z"></path>
  </symbol>
  <symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" id="github">
    <path d="M255.968 5.329C114.624 5.329 0 120.401 0 262.353c0 113.536 73.344 209.856 175.104 243.872 12.8 2.368 17.472-5.568 17.472-12.384 0-6.112-.224-22.272-.352-43.712-71.2 15.52-86.24-34.464-86.24-34.464-11.616-29.696-28.416-37.6-28.416-37.6-23.264-15.936 1.728-15.616 1.728-15.616 25.696 1.824 39.2 26.496 39.2 26.496 22.848 39.264 59.936 27.936 74.528 21.344 2.304-16.608 8.928-27.936 16.256-34.368-56.832-6.496-116.608-28.544-116.608-127.008 0-28.064 9.984-51.008 26.368-68.992-2.656-6.496-11.424-32.64 2.496-68 0 0 21.504-6.912 70.4 26.336 20.416-5.696 42.304-8.544 64.096-8.64 21.728.128 43.648 2.944 64.096 8.672 48.864-33.248 70.336-26.336 70.336-26.336 13.952 35.392 5.184 61.504 2.56 68 16.416 17.984 26.304 40.928 26.304 68.992 0 98.72-59.84 120.448-116.864 126.816 9.184 7.936 17.376 23.616 17.376 47.584 0 34.368-.32 62.08-.32 70.496 0 6.88 4.608 14.88 17.6 12.352C438.72 472.145 512 375.857 512 262.353 512 120.401 397.376 5.329 255.968 5.329z"></path>
  </symbol>

  <symbol width="128px" height="128px" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" id="gitee">
      <g id="LOGO" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
          <g id="Artboard-7" transform="translate(-192.000000, -115.000000)" fill="#C71D23">
              <path d="M228,115 C247.882251,115 264,131.117749 264,151 C264,170.882251 247.882251,187 228,187 C208.117749,187 192,170.882251 192,151 C192,131.117749 208.117749,115 228,115 Z M246.223335,131 C246.222967,131 246.2226,131 246.222232,131.001102 L221.33326,131.001102 C213.969504,131.001102 208,136.970606 208,144.334362 L208,169.222232 C208,170.204066 208.795934,171 209.777768,171 L236.000329,171 C242.627564,171 248,165.627564 248,159.000329 L248,148.778425 C248,147.796591 247.204066,147.000657 246.222232,147.000657 L225.7779,147.000657 C224.796248,147.001123 224.000389,147.796773 223.999667,148.778425 L223.998503,153.222667 C223.997802,154.155409 224.715909,154.920565 225.629522,154.994969 L225.775805,155.00042 L225.775805,155.00042 L238.222276,155.000317 C239.155019,155.000295 239.919992,155.718618 239.994164,156.63225 L240.000044,156.77807 L240.000044,156.77807 L240.000044,157.666909 C240.000044,160.612411 237.612243,163.000213 234.66674,163.000213 L217.776621,163.000213 C216.794928,163.000164 215.999101,162.204358 215.999025,161.222665 L215.998559,144.334184 C215.998337,141.462319 218.268172,139.120556 221.111731,139.005187 L221.331716,139.00088 L221.331716,139.00088 L246.21727,139.00088 C247.198674,138.999777 247.994429,138.204515 247.996141,137.223112 L247.998897,132.77887 C248.000609,131.797037 247.205169,131.000609 246.223335,131 Z" id="logo_gitee_g_red"></path>
          </g>
      </g>
  </symbol>

  <symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 212 212" id="gitlab">
    <path d="M12.3 74.7h54L43.3 3c-1-3.6-6.4-3.6-7.6 0L12.3 74.8z" />
    <path d="M12.3 74.7L.5 111c-1 3.2 0 6.8 3 8.8l101.6 74-92.5-119z"/>
    <path d="M105 193.7l-38.6-119h-54l92.7 119z"/>
    <path d="M105 193.7l38.7-119H66.4l38.7 119z"/>
    <path d="M105 193.7l38.7-119H198l-93 119z"/>
    <path d="M198 74.7l11.6 36.2c1 3 0 6.6-3 8.6l-101.5 74 93-119z"/>
    <path d="M198 74.7h-54.3L167 3c1.2-3.6 6.4-3.6 7.6 0L198 74.8z"/>
  </symbol>
  <symbol viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" id="rss">
    <circle cx="3.429" cy="20.571" r="3.429"></circle>
    <path d="M11.429 24h4.57C15.999 15.179 8.821 8.001 0 8v4.572c6.302.001 11.429 5.126 11.429 11.428z"></path>
    <path d="M24 24C24 10.766 13.234 0 0 0v4.571c10.714 0 19.43 8.714 19.43 19.429z"></path>
  </symbol>
  <symbol viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" id="linkedin">
    <path d="M437 0H75C33.648 0 0 33.648 0 75v362c0 41.352 33.648 75 75 75h362c41.352 0 75-33.648 75-75V75c0-41.352-33.648-75-75-75zM181 406h-60V196h60zm0-240h-60v-60h60zm210 240h-60V286c0-16.54-13.46-30-30-30s-30 13.46-30 30v120h-60V196h60v11.309C286.719 202.422 296.93 196 316 196c40.691.043 75 36.547 75 79.688zm0 0"></path>
  </symbol>
  <symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 612 612" id="to-top">
    <path d="M604.501 440.509L325.398 134.956c-5.331-5.357-12.423-7.627-19.386-7.27-6.989-.357-14.056 1.913-19.387 7.27L7.499 440.509c-9.999 10.024-9.999 26.298 0 36.323s26.223 10.024 36.222 0l262.293-287.164L568.28 476.832c9.999 10.024 26.222 10.024 36.221 0 9.999-10.023 9.999-26.298 0-36.323z"></path>
  </symbol>
  <symbol viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" id="carly">
    <path d="M504.971 239.029L448 182.059V84c0-46.317-37.682-84-84-84h-44c-13.255 0-24 10.745-24 24s10.745 24 24 24h44c19.851 0 36 16.149 36 36v108c0 6.365 2.529 12.47 7.029 16.971L454.059 256l-47.029 47.029A24.002 24.002 0 0 0 400 320v108c0 19.851-16.149 36-36 36h-44c-13.255 0-24 10.745-24 24s10.745 24 24 24h44c46.318 0 84-37.683 84-84v-98.059l56.971-56.971c9.372-9.372 9.372-24.568 0-33.941zM112 192V84c0-19.851 16.149-36 36-36h44c13.255 0 24-10.745 24-24S205.255 0 192 0h-44c-46.318 0-84 37.683-84 84v98.059l-56.971 56.97c-9.373 9.373-9.373 24.568 0 33.941L64 329.941V428c0 46.317 37.682 84 84 84h44c13.255 0 24-10.745 24-24s-10.745-24-24-24h-44c-19.851 0-36-16.149-36-36V320c0-6.365-2.529-12.47-7.029-16.971L57.941 256l47.029-47.029A24.002 24.002 0 0 0 112 192z"></path>
  </symbol>
  <symbol viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" id="copy">
    <path d="M23 2.75A2.75 2.75 0 0 0 20.25 0H8.75A2.75 2.75 0 0 0 6 2.75v13.5A2.75 2.75 0 0 0 8.75 19h11.5A2.75 2.75 0 0 0 23 16.25zM18.25 14.5h-7.5a.75.75 0 0 1 0-1.5h7.5a.75.75 0 0 1 0 1.5zm0-3h-7.5a.75.75 0 0 1 0-1.5h7.5a.75.75 0 0 1 0 1.5zm0-3h-7.5a.75.75 0 0 1 0-1.5h7.5a.75.75 0 0 1 0 1.5z"></path>
    <path d="M8.75 20.5a4.255 4.255 0 0 1-4.25-4.25V2.75c0-.086.02-.166.025-.25H3.75A2.752 2.752 0 0 0 1 5.25v16A2.752 2.752 0 0 0 3.75 24h12a2.752 2.752 0 0 0 2.75-2.75v-.75z"></path>
  </symbol>
  <symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512.001 512.001" id="closeme">
    <path d="M284.286 256.002L506.143 34.144c7.811-7.811 7.811-20.475 0-28.285-7.811-7.81-20.475-7.811-28.285 0L256 227.717 34.143 5.859c-7.811-7.811-20.475-7.811-28.285 0-7.81 7.811-7.811 20.475 0 28.285l221.857 221.857L5.858 477.859c-7.811 7.811-7.811 20.475 0 28.285a19.938 19.938 0 0 0 14.143 5.857 19.94 19.94 0 0 0 14.143-5.857L256 284.287l221.857 221.857c3.905 3.905 9.024 5.857 14.143 5.857s10.237-1.952 14.143-5.857c7.811-7.811 7.811-20.475 0-28.285L284.286 256.002z"></path>
  </symbol>
  <symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" id="open-menu">
    <path d="M492 236H20c-11.046 0-20 8.954-20 20s8.954 20 20 20h472c11.046 0 20-8.954 20-20s-8.954-20-20-20zm0-160H20C8.954 76 0 84.954 0 96s8.954 20 20 20h472c11.046 0 20-8.954 20-20s-8.954-20-20-20zm0 320H20c-11.046 0-20 8.954-20 20s8.954 20 20 20h472c11.046 0 20-8.954 20-20s-8.954-20-20-20z"></path>
  </symbol>
  <symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" id="instagram">
    <path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98-1.281-.059-1.69-.073-4.949-.073zm0 5.838c-3.403 0-6.162 2.759-6.162 6.162s2.759 6.163 6.162 6.163 6.162-2.759 6.162-6.163c0-3.403-2.759-6.162-6.162-6.162zm0 10.162c-2.209 0-4-1.79-4-4 0-2.209 1.791-4 4-4s4 1.791 4 4c0 2.21-1.791 4-4 4zm6.406-11.845c-.796 0-1.441.645-1.441 1.44s.645 1.44 1.441 1.44c.795 0 1.439-.645 1.439-1.44s-.644-1.44-1.439-1.44z"/>
  </symbol>
  <symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" id=youtube>
    <path d="M19.615 3.184c-3.604-.246-11.631-.245-15.23 0-3.897.266-4.356 2.62-4.385 8.816.029 6.185.484 8.549 4.385 8.816 3.6.245 11.626.246 15.23 0 3.897-.266 4.356-2.62 4.385-8.816-.029-6.185-.484-8.549-4.385-8.816zm-10.615 12.816v-8l8 3.993-8 4.007z"/>
  </symbol>
  <symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" id="stackoverflow">
    <path d="M21 27v-8h3v11H0V19h3v8h18z"></path><path d="M17.1.2L15 1.8l7.9 10.6 2.1-1.6L17.1.2zm3.7 14.7L10.6 6.4l1.7-2 10.2 8.5-1.7 2zM7.2 12.3l12 5.6 1.1-2.4-12-5.6-1.1 2.4zm-1.8 6.8l13.56 1.96.17-2.38-13.26-2.55-.47 2.97zM19 25H5v-3h14v3z"></path>
  </symbol>
  <symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" id="xing">
    <path d="M18.188 0c-.517 0-.741.325-.927.66 0 0-7.455 13.224-7.702 13.657.015.024 4.919 9.023 4.919 9.023.17.308.436.66.967.66h3.454c.211 0 .375-.078.463-.22.089-.151.089-.346-.009-.536l-4.879-8.916c-.004-.006-.004-.016 0-.022L22.139.756c.095-.191.097-.387.006-.535C22.056.078 21.894 0 21.686 0h-3.498zM3.648 4.74c-.211 0-.385.074-.473.216-.09.149-.078.339.02.531l2.34 4.05c.004.01.004.016 0 .021L1.86 16.051c-.099.188-.093.381 0 .529.085.142.239.234.45.234h3.461c.518 0 .766-.348.945-.667l3.734-6.609-2.378-4.155c-.172-.315-.434-.659-.962-.659H3.648v.016z"/>
  </symbol>
  <symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 71 55" id="discord">
    <path d="M60.1045 4.8978C55.5792 2.8214 50.7265 1.2916 45.6527 0.41542C45.5603 0.39851 45.468 0.440769 45.4204 0.525289C44.7963 1.6353 44.105 3.0834 43.6209 4.2216C38.1637 3.4046 32.7345 3.4046 27.3892 4.2216C26.905 3.0581 26.1886 1.6353 25.5617 0.525289C25.5141 0.443589 25.4218 0.40133 25.3294 0.41542C20.2584 1.2888 15.4057 2.8186 10.8776 4.8978C10.8384 4.9147 10.8048 4.9429 10.7825 4.9795C1.57795 18.7309 -0.943561 32.1443 0.293408 45.3914C0.299005 45.4562 0.335386 45.5182 0.385761 45.5576C6.45866 50.0174 12.3413 52.7249 18.1147 54.5195C18.2071 54.5477 18.305 54.5139 18.3638 54.4378C19.7295 52.5728 20.9469 50.6063 21.9907 48.5383C22.0523 48.4172 21.9935 48.2735 21.8676 48.2256C19.9366 47.4931 18.0979 46.6 16.3292 45.5858C16.1893 45.5041 16.1781 45.304 16.3068 45.2082C16.679 44.9293 17.0513 44.6391 17.4067 44.3461C17.471 44.2926 17.5606 44.2813 17.6362 44.3151C29.2558 49.6202 41.8354 49.6202 53.3179 44.3151C53.3935 44.2785 53.4831 44.2898 53.5502 44.3433C53.9057 44.6363 54.2779 44.9293 54.6529 45.2082C54.7816 45.304 54.7732 45.5041 54.6333 45.5858C52.8646 46.6197 51.0259 47.4931 49.0921 48.2228C48.9662 48.2707 48.9102 48.4172 48.9718 48.5383C50.038 50.6034 51.2554 52.5699 52.5959 54.435C52.6519 54.5139 52.7526 54.5477 52.845 54.5195C58.6464 52.7249 64.529 50.0174 70.6019 45.5576C70.6551 45.5182 70.6887 45.459 70.6943 45.3942C72.1747 30.0791 68.2147 16.7757 60.1968 4.9823C60.1772 4.9429 60.1437 4.9147 60.1045 4.8978ZM23.7259 37.3253C20.2276 37.3253 17.3451 34.1136 17.3451 30.1693C17.3451 26.225 20.1717 23.0133 23.7259 23.0133C27.308 23.0133 30.1626 26.2532 30.1066 30.1693C30.1066 34.1136 27.28 37.3253 23.7259 37.3253ZM47.3178 37.3253C43.8196 37.3253 40.9371 34.1136 40.9371 30.1693C40.9371 26.225 43.7636 23.0133 47.3178 23.0133C50.9 23.0133 53.7545 26.2532 53.6986 30.1693C53.6986 34.1136 50.9 37.3253 47.3178 37.3253Z"/>
  </symbol>
  <symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 17 18" id="mastodon">
    <path
    fill="#ffffff"
    d="m 15.054695,9.8859583 c -0.22611,1.1632697 -2.02517,2.4363497 -4.09138,2.6830797 -1.0774504,0.12856 -2.1382704,0.24673 -3.2694704,0.19484 -1.84996,-0.0848 -3.30971,-0.44157 -3.30971,-0.44157 0,0.1801 0.0111,0.35157 0.0333,0.51194 0.24051,1.82571 1.81034,1.93508 3.29737,1.98607 1.50088,0.0514 2.8373104,-0.37004 2.8373104,-0.37004 l 0.0617,1.35686 c 0,0 -1.0498104,0.56374 -2.9199404,0.66742 -1.03124,0.0567 -2.3117,-0.0259 -3.80308,-0.42069 -3.23454998,-0.85613 -3.79081998,-4.304 -3.87592998,-7.8024197 -0.026,-1.03871 -0.01,-2.01815 -0.01,-2.83732 0,-3.57732 2.34385998,-4.62587996 2.34385998,-4.62587996 1.18184,-0.54277 3.20976,-0.77101 5.318,-0.7882499985409 h 0.0518 C 9.8267646,0.01719834 11.856025,0.24547834 13.037775,0.78824834 c 0,0 2.34377,1.04855996 2.34377,4.62587996 0,0 0.0294,2.63937 -0.32687,4.47183"/>
 <path
    fill="#000000"
    d="m 12.616925,5.6916583 v 4.3315297 h -1.71607 V 5.8189683 c 0,-0.88624 -0.37289,-1.33607 -1.1187604,-1.33607 -0.82467,0 -1.23799,0.53361 -1.23799,1.58875 v 2.30122 h -1.70594 v -2.30122 c 0,-1.05514 -0.4134,-1.58875 -1.23808,-1.58875 -0.74587,0 -1.11876,0.44983 -1.11876,1.33607 v 4.2042197 h -1.71607 V 5.6916583 c 0,-0.88527 0.22541,-1.58876 0.67817,-2.10922 0.46689,-0.52047 1.07833,-0.78727 1.83735,-0.78727 0.87816,0 1.54317,0.33752 1.98288,1.01267 l 0.42744,0.71655 0.42753,-0.71655 c 0.43961,-0.67515 1.10463,-1.01267 1.9828704,-1.01267 0.75893,0 1.37037,0.2668 1.83735,0.78727 0.45268,0.52046 0.67808,1.22395 0.67808,2.10922"/>
  </symbol>
</svg>

<footer class="footer">
  <div class="footer_inner wrap pale">
    <img src='https://kingdix10.gitee.io/icons/copy.svg' class="icon icon_2 transparent" alt="拾月国度">
    <p>Copyright&nbsp;2018-&nbsp;<span class="year"></span>&nbsp;拾月国度. All Rights Reserved</p><a class="to_top" href="#documentTop">
  <svg class="icon">
  <title>to-top</title>
  <use xlink:href="#to-top"></use>
</svg>

</a>

  </div>
</footer>

<script type="text/javascript" src="https://kingdix10.gitee.io/zh-cn/js/bundle.352f6b8ac853443fc909370d968a769ffa303b36042cc66849f2d48d9e5dd951ee86c06130908f5d77ea0e55ec8fed0e5dc26f0f14bbd4ad6dcf35999232e5bc.js" integrity="sha512-NS9rishTRD/JCTcNlop2n/owOzYELMZoSfLUjZ5d2VHuhsBhMJCPXXfqDlXsj&#43;0OXcJvDxS71K1tzzWZkjLlvA==" crossorigin="anonymous"></script>

  <script src="https://kingdix10.gitee.io/js/search.min.b19f217359693afb8f0abd75ca8de6becceec41f5304950fc48e165914ef227f44d10005d02a281a66e33b482e2ff27e6eb893111505deb4f072c307e1f887bb.js"></script>

  </body>
</html>
